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__()
Функция вызывается для инициализации после создания объекта.