Python вызывает классы динамически

Я хочу вызывать классы 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

<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 ответа

Решение

Вы получаете модуль, а не класс в модуле; __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)

Из документации__import__() -

__import __ (name [, globals [, localals[, fromlist[, level]]]])

Когда переменная name имеет форму package.module, обычно возвращается пакет верхнего уровня (имя до первой точки), а не модуль, названный по имени. Однако, когда задан непустой аргумент fromlist, возвращается модуль с именем name.

(Акцент мой)

Так что в вашем случае модуль - fuzzymodules возвращается - не модуль, содержащий ваш класс.

Вы должны указать fromlist аргумент как name, Пример -

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

Кроме того, другая проблема заключается в том, что вы не должны напрямую вызывать __init__() функция класса, чтобы создать объект для него, вместо этого вызвать его напрямую, Пример -

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

__init__() Функция вызывается для инициализации после создания объекта.

Другие вопросы по тегам