有人能为我提供一个导入整个模块目录的好方法吗? 我有一个这样的结构:
/Foo
bar.py
spam.py
eggs.py
我尝试通过添加__init__.py并从Foo import *将其转换为一个包,但它没有按我希望的方式工作。
有人能为我提供一个导入整个模块目录的好方法吗? 我有一个这样的结构:
/Foo
bar.py
spam.py
eggs.py
我尝试通过添加__init__.py并从Foo import *将其转换为一个包,但它没有按我希望的方式工作。
当前回答
我想补充Anurag Uniyal的回答。 你可以让它变得更简单,去掉大量的导入。 __init__.py文件的内容:
from os import listdir
from os.path import dirname
__all__ = [i[:-3] for i in listdir(dirname(__file__)) if not i.startswith('__') and i.endswith('.py')]
其他回答
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
for imp, module, ispackage in pkgutil.walk_packages(path=__path__, prefix=__name__+'.'):
__import__(module)
我自己也厌倦了这个问题,所以我写了一个名为automodinit的包来解决它。你可以从http://pypi.python.org/pypi/automodinit/上得到它。
用法是这样的:
将automodinit包包含到setup.py依赖项中。 像这样替换所有__init__.py文件:
__all__ = ["I will get rewritten"] # Don't modify the line above, or this line! import automodinit automodinit.automodinit(__name__, __file__, globals()) del automodinit # Anything else you want can go after here, it won't get modified.
就是这样!从现在开始导入一个模块将设置__all__为 模块中的.py[co]文件列表,也将导入每个文件 就好像你输入了:
for x in __all__: import x
因此,“from M import *”的效果与“import M”完全匹配。
automodinit从ZIP档案内部运行,因此是ZIP安全的。
尼尔
这里有一个解决方案,您不必写文件名。只需将此代码片段添加到__init__.py中
from inspect import isclass
from pkgutil import iter_modules
from pathlib import Path
from importlib import import_module
# iterate through the modules in the current package
package_dir = Path(__file__).resolve().parent
for (_, module_name, _) in iter_modules([package_dir]):
# import the module and iterate through its attributes
module = import_module(f"{__name__}.{module_name}")
for attribute_name in dir(module):
attribute = getattr(module, attribute_name)
if isclass(attribute):
# Add the class to this package's variables
globals()[attribute_name] = attribute
源
Anurag的例子有几个更正:
import os, glob
modules = glob.glob(os.path.join(os.path.dirname(__file__), "*.py"))
__all__ = [os.path.basename(f)[:-3] for f in modules if not f.endswith("__init__.py")]
我知道我正在更新一个相当旧的帖子,我尝试使用automodinit,但发现它的设置过程对python3是坏的。所以,基于Luca的回答,我想出了一个更简单的答案——可能不适合。zip——来解决这个问题,所以我想我应该在这里分享它:
在你的包的__init__.py模块中:
#!/usr/bin/env python
import os, pkgutil
__all__ = list(module for _, module, _ in pkgutil.iter_modules([os.path.dirname(__file__)]))
在你的包下面的另一个包里:
from yourpackage import *
然后,您将加载包中放置的所有模块,如果您编写了一个新模块,它也将被自动导入。当然,要小心使用这些东西,能力越大责任越大。