Python:如何从目录中的所有模块导入?

14

目录结构:

main.py
my_modules/
   module1.py
   module2.py

module1.py:

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

如何将module*中的所有类添加到主文件中而不带前缀(即像使用fooBar()这样使用它们,而不是my_modules.module1.fooBar())。

一个显而易见的决策是在main.py文件中编写类似以下内容的代码:

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

但是我不想在创建新的moduleN时改变main.py。有解决方案吗?

我知道像这样导入类不是一个好主意,但我仍然很好奇。

更新:这个问题与这个问题Loading all modules in a folder in Python不同,因为我的问题是加载没有命名空间的模块。


1
你是指Python中的动态模块导入吗?https://dev59.com/hXVC5IYBdhLWcg3wbQbA - Rahul K
动态模块导入对于这个问题来说是一个相当复杂的解决方案,我认为。 - ov7a
1个回答

38
my_modules文件夹中添加一个__init__.py文件,使它成为一个合适的包。在该文件中,您可以将这些模块的全局变量注入到__init__.py文件的全局范围内,这样它们就可以在导入您的模块时使用(在您还将全局名称添加到__all__变量之后):
__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,你只能使用最后导入的那一个。


以上代码可以放在__init__.py文件中吗?还是应该放在其他地方以便自动导入模块? - nish
正是我想要的。然而,find_module自3.3版本起已被弃用。 - VPfB
非常感谢 - 我已经寻找了一段时间,寻找这种便携式(zip或模块)导入包中所有模块的方法 - 这个方法完美地解决了我的问题! - Chuck Buche
loader.find_module(name).load_module(name)的一个更简单的替代方案是importlib.import_module(name) - llf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接