python动态调用类

时间:2015-07-25 14:44:36

标签: python python-2.7 getattr

我想动态调用python类,

这些是我想要调用的类

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

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

这些类也位于 fuzzymodules 文件夹

我从** FuzzyComparisonPipeline.py **中调用它们,它与 fuzzymodules 在同一目录中,如下所示:

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

我收到了这个错误:

   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)

我的问题是 init ()如何接受2个参数,如你所见,在两个类中 init 接受三个参数

你能帮忙吗

我不能给你整个代码,因为它太复杂了,其他一切都运行正常,我很确定,我的问题在于调用该函数。

来自此xml的 for 循环的值

<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>

2 个答案:

答案 0 :(得分:3)

您正在检索模块,而不是模块中的类; __import__()函数返回顶级包,而不是嵌套模块本身。

你真的想在这里使用importlib.import_module(),它的行为与你期望的一样。

接下来,您要调用这样检索的类对象,而不是直接调用__init__方法。让 Python 为你调用它,它会通过调用类来初始化你创建的实例:

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)

答案 1 :(得分:2)

来自documentation of __import__() -

  

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

     

当name变量的格式为package.module时,通常会返回顶级包(直到第一个点的名称),而不是名称命名的模块。但是,当给出非空的fromlist参数时,将返回按名称命名的模块。

(强调我的)

因此,在您的情况下,正在返回模块 - fuzzymodules - 而不是包含您的类的模块。

您应将fromlist参数指定为name。示例 -

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

另外,另一个问题是你不应该直接调用类的__init__()函数为它创建一个对象,而是直接调用它,例如 -

instanceOfModule = getattr(module_to_import, name)(configurationLoader, moduleConfigurationFile, settings)
在创建对象后,将调用

__init__()函数进行初始化。