Подтвердить что ты не робот

Python: как импортировать из всех модулей в каталоге?

Структура Dir:

main.py
my_modules/
   module1.py
   module2.py

module1.py:

class fooBar():
    ....
class pew_pew_FooBarr()
    ....
...

Как я могу добавить все классы из модуля * в main без префиксов (например, использовать их как foo = fooBar(), а не foo = my_modules.module1.fooBar()).

Очевидным решением является написать в main.py что-то вроде этого:

from my_modules.module1 import *
from my_modules.module2 import *
from my_modules.module3 import *
...

Но я не хочу менять main.py при создании нового модуляN. Есть ли решение для этого?

Я знаю, что не рекомендуется импортировать классы, подобные этому, но мне все еще интересно.

UPD: этот вопрос отличается от этого Загрузка всех модулей в папку на Python, потому что моя проблема заключается в загрузке модулей без пространств имен.

4b9b3361

Ответ 1

В папке my_modules добавьте файл __init__.py, чтобы сделать его подходящим. В этом файле вы можете вводить глобалы каждого из этих модулей в глобальную область файла __init__.py, что делает их доступными по мере импорта вашего модуля (после того, как вы также добавили имя глобального в __all__ variable):

__all__ = []

import pkgutil
import inspect

for loader, name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(name).load_module(name)

    for name, value in inspect.getmembers(module):
        if name.startswith('__'):
            continue

        globals()[name] = value
        __all__.append(name)

Теперь вместо выполнения:

from my_modules.class1 import Stuff

Вы можете просто сделать:

from my_modules import Stuff

Или импортировать все в глобальную область видимости, которая, по-видимому, вы хотите сделать:

from my_modules import *

Проблема с этим подходом заключается в том, что классы перезаписывают друг друга, поэтому, если два модуля предоставляют Foo, вы сможете использовать только тот, который был импортирован последним.