有人能为我提供一个导入整个模块目录的好方法吗? 我有一个这样的结构:
/Foo
bar.py
spam.py
eggs.py
我尝试通过添加__init__.py并从Foo import *将其转换为一个包,但它没有按我希望的方式工作。
有人能为我提供一个导入整个模块目录的好方法吗? 我有一个这样的结构:
/Foo
bar.py
spam.py
eggs.py
我尝试通过添加__init__.py并从Foo import *将其转换为一个包,但它没有按我希望的方式工作。
当前回答
我有一个嵌套的目录结构,即在包含python模块的主目录中有多个目录。
我在__init__.py文件中添加了以下脚本以导入所有模块
import glob, re, os
module_parent_directory = "path/to/the/directory/containing/__init__.py/file"
owd = os.getcwd()
if not owd.endswith(module_parent_directory): os.chdir(module_parent_directory)
module_paths = glob.glob("**/*.py", recursive = True)
for module_path in module_paths:
if not re.match( ".*__init__.py$", module_path):
import_path = module_path[:-3]
import_path = import_path.replace("/", ".")
exec(f"from .{import_path} import *")
os.chdir(owd)
也许这不是实现这一目标的最佳方式,但除此之外我没有别的办法。
其他回答
列出当前文件夹中的所有python (.py)文件,并将它们作为__init__.py中的__all__变量
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
将__all__变量添加到__init__.py,包含:
__all__ = ["bar", "spam", "eggs"]
参见http://docs.python.org/tutorial/modules.html
只需通过importlib导入它们,并在包的__init__.py中递归地将它们添加到__all__(添加操作是可选的)。
/Foo
bar.py
spam.py
eggs.py
__init__.py
# __init__.py
import os
import importlib
pyfile_extes = ['py', ]
__all__ = [importlib.import_module('.%s' % filename, __package__) for filename in [os.path.splitext(i)[0] for i in os.listdir(os.path.dirname(__file__)) if os.path.splitext(i)[1] in pyfile_extes] if not filename.startswith('__')]
del os, importlib, pyfile_extes
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
for imp, module, ispackage in pkgutil.walk_packages(path=__path__, prefix=__name__+'.'):
__import__(module)
何时从。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是为了避免在已经导入模块时重新导入模块,因为这可能存在循环导入的风险。