Python calls classes dynamically

I want to dynamically call python classes,

These are the classes I want to name

class AutosoukModelMakeFuzzyComparisonModule:
    def __init__(self,configurationLoader=None, moduleConfigurationFile=None, settings=None):
        pass

      

and

class DefaultFuzzyComparisonModule:
    def __init__(self,configurationLoader, moduleConfigurationFile, settings = None):
        pass

      

and these classes located in fuzzymodules folder

and I'm calling them from ** FuzzyComparisonPipeline.py ** which is in the same directory as fuzzymodules like this:

for module in FuzzyComparisonPipeline.fuzzyModules:
        name = module['name']
        configurationLoader = module['configurationLoader']
        moduleConfigurationFile = module['moduleConfigurationFile']
        settings = module['settings']
        module_to_import = __import__('fuzzymodules.'+name)
        instanceOfModule = getattr(module_to_import, name).__init__(configurationLoader, moduleConfigurationFile, settings)
        #instanceOfModule(configurationLoader, moduleConfigurationFile, settings)
    return item

      

I got this error:

   Traceback (most recent call last):
  File "path to my FuzzyComparisonPipeline.py", line 9, in process_item
    instanceOfModule = getattr(module_to_import, name).__init__(configurationLoader, moduleConfigurationFile, settings)
TypeError: module.__init__() takes at most 2 arguments (3 given)

      

and my question is how init () takes 2 arguments, as you can see in both classes init takes 3 arguments

Could you help me?

I cannot give you the whole code because it is so complex that everything else works fine, I am sure of that, my problem is the call to this function.

loop values for coming from this xml

<FuzzyComparison>
    <Modules>
        <Module>
            <name>AutosoukModelMakeFuzzyComparisonModule</name>
            <configurationLoader>DefaultLoader</configurationLoader>
            <configurationFile>MakesModels.conf</configurationFile>
            <settings></settings>
        </Module>
        <Module>
            <name>DefaultFuzzyComparisonModule</name>
            <configurationLoader>DefaultLoader</configurationLoader>
            <configurationFile>Buildings.conf</configurationFile>
            <settings>
                <attribute>building</attribute>
                <second>2222duxk fuck fuck</second>
            </settings>
        </Module>
    </Modules>
    </FuzzyComparison>

      

+3


source to share


2 answers


You are retrieving a module, not a class in a module; the function __import__()

returns the top-level package, not the nested module itself.

Do you really want to use it importlib.import_module()

instead, it behaves as you expect.



Next, you want to call the class object obtained this way, not the method __init__

. Let Python call this for you, it will do this to initialize the instantiated instance by calling the class:

from importlib import import_module

for module in FuzzyComparisonPipeline.fuzzyModules:
    name = module['name']
    configurationLoader = module['configurationLoader']
    moduleConfigurationFile = module['moduleConfigurationFile']
    settings = module['settings']
    module_to_import = import_module('fuzzymodules.' + name)
    instance = getattr(module_to_import, name)(configurationLoader, moduleConfigurationFile, settings)

      

+3


source


From the documentation__import__()

-

__ import __ (name [, globals [, locals [, fromlist [, level]]]])

When the name variable is of the form package.module, it will usually return the top-level package (name up to first dot) rather than a module named by name. However, when a non-empty fromlist argument is given, a named module is returned.

(Emphasis mine)

So, in your case, the returned module is fuzzymodules

- not the module that contains your class.

You must specify the argument fromlist

as name

. Example -



module_to_import = __import__('fuzzymodules.'+name, fromlist=name)

      


Also, another problem is that you shouldn't directly call a __init__()

class function to create an object for it, instead call it directly, Example -

instanceOfModule = getattr(module_to_import, name)(configurationLoader, moduleConfigurationFile, settings)

      

__init__()

function is called to initialize after object creation.

+2


source







All Articles