有人能为我提供一个导入整个模块目录的好方法吗? 我有一个这样的结构:

/Foo
    bar.py
    spam.py
    eggs.py

我尝试通过添加__init__.py并从Foo import *将其转换为一个包,但它没有按我希望的方式工作。


当前回答

import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
for imp, module, ispackage in pkgutil.walk_packages(path=__path__, prefix=__name__+'.'):
  __import__(module)

其他回答

看看标准库中的pkgutil模块。只要目录中有__init__.py文件,它就会让你做你想做的事情。__init__.py文件可以为空。

我想补充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')]

这里有一个解决方案,您不必写文件名。只需将此代码片段添加到__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

我已经为此创建了一个模块,它不依赖于__init__.py(或任何其他辅助文件),并让我只输入以下两行:

import importdir
importdir.do("Foo", globals())

请随意重用或贡献:http://gitlab.com/aurelien-lourot/importdir

使用importlib,唯一需要添加的是

from importlib import import_module
from pathlib import Path

__all__ = [
    import_module(f".{f.stem}", __package__)
    for f in Path(__file__).parent.glob("*.py")
    if "__" not in f.stem
]
del import_module, Path