У меня есть пакеты, содержащие классы C1, C2, CInvalid3, C4
, которые определены в разных подблоках.Сбор некоторых конкретных классов в модуле python
my_package/
__init__.py
sub_package1/
__init__.py
sub_module1.py # contains C1, C2
sub_package2/
__init__.py
sub_module2.py # contains CInvalid3, C4
Для строки, содержащей имя какого-либо класса, я хочу инициализировать соответствующий класс. Например,
some_valid_class_name = 'C1'
some_valid_class = all_valid_classes[some_valid_class_name]()
В настоящее время я создаю модуль all_classes.py
под my_package
, который содержит
all_valid_classes = {} # I want the dict contain C1, C2 and C4
def this_is_a_valid_class(cls):
all_valid_classes[cls.__name__] = cls
return cls
И в sub_module1.py
и sub_module2.py
, я использую
from my_package.all_classes import this_is_a_valid_class
@this_is_a_valid_class
class C1(object):
pass
и добавить
from .sub_package1 import sub_module1
from .sub_package2 import sub_module2
до my_package/__init__.py
.
Есть ли лучший способ справиться с этим? Я импортирую все вещи в my_package/__init__.py
. Когда я добавляю новый sub_package3.sub_module3.C99
, мне нужно помнить, чтобы добавить from .sub_package3 import sub_module3
в my_package/__init__.py
. Я не думаю, что это хорошие идеи.
FYI, '__init __. Py' может содержать важный код (' import foo' примерно эквивалентен, если верхний уровень каталога импорта содержит 'foo.py' или каталог с именем' foo', содержащий '__init __. Py'; если содержимое 'foo.py' и' foo/__ init __. py' одинаково, 'import foo' будет вести себя одинаково). Вы хотите обрабатывать '__init __. Py' тоже, не пропустите его. – ShadowRanger
@ShadowRanger при импорте модулей внутри каталога файл '__init __. Py' импортируется автоматически, поэтому мы не пропускаем их в этом случае. – pacha
Вы импортируете их, но вы не сканируете их для классов, поэтому любой класс, определенный исключительно в '__init __. Py', не будет найден. Пример, который хранит определения классов только в '__init__.py', см. собственный модуль 'collections' Python; определения Python вещей, которые не находятся в 'collection.abc', находятся только в' collection/__ init __. py'. – ShadowRanger