有人能为我提供一个导入整个模块目录的好方法吗? 我有一个这样的结构:
/Foo
bar.py
spam.py
eggs.py
我尝试通过添加__init__.py并从Foo import *将其转换为一个包,但它没有按我希望的方式工作。
有人能为我提供一个导入整个模块目录的好方法吗? 我有一个这样的结构:
/Foo
bar.py
spam.py
eggs.py
我尝试通过添加__init__.py并从Foo import *将其转换为一个包,但它没有按我希望的方式工作。
当前回答
我已经为此创建了一个模块,它不依赖于__init__.py(或任何其他辅助文件),并让我只输入以下两行:
import importdir
importdir.do("Foo", globals())
请随意重用或贡献:http://gitlab.com/aurelien-lourot/importdir
其他回答
Anurag Uniyal给出了改进建议!
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import os
import glob
all_list = list()
for f in glob.glob(os.path.dirname(__file__)+"/*.py"):
if os.path.isfile(f) and not os.path.basename(f).startswith('_'):
all_list.append(os.path.basename(f)[:-3])
__all__ = all_list
我想补充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 *不够好,这是对ted的回答的改进。具体来说,这种方法不需要使用__all__。
"""Import all modules that exist in the current directory."""
# Ref https://stackoverflow.com/a/60861023/
from importlib import import_module
from pathlib import Path
for f in Path(__file__).parent.glob("*.py"):
module_name = f.stem
if (not module_name.startswith("_")) and (module_name not in globals()):
import_module(f".{module_name}", __package__)
del f, module_name
del import_module, Path
请注意,globals()中没有module_name是为了避免在已经导入模块时重新导入模块,因为这可能存在循环导入的风险。
扩展Mihail的回答,我认为非黑客的方式(即不直接处理文件路径)如下:
在Foo/下创建一个空的__init__.py文件 执行
import pkgutil
import sys
def load_all_modules_from_dir(dirname):
for importer, package_name, _ in pkgutil.iter_modules([dirname]):
full_package_name = '%s.%s' % (dirname, package_name)
if full_package_name not in sys.modules:
module = importer.find_module(package_name
).load_module(full_package_name)
print module
load_all_modules_from_dir('Foo')
你会得到:
<module 'Foo.bar' from '/home/.../Foo/bar.pyc'>
<module 'Foo.spam' from '/home/.../Foo/spam.pyc'>
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
for imp, module, ispackage in pkgutil.walk_packages(path=__path__, prefix=__name__+'.'):
__import__(module)