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

/Foo
    bar.py
    spam.py
    eggs.py

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


当前回答

2017年更新:你可能想用importlib代替。

通过添加__init__.py使Foo目录成为一个包。在__init__.py中添加:

import bar
import eggs
import spam

因为你希望它是动态的(这可能是也可能不是一个好主意),用list dir列出所有的py-files,然后像这样导入它们:

import os
for module in os.listdir(os.path.dirname(__file__)):
    if module == '__init__.py' or module[-3:] != '.py':
        continue
    __import__(module[:-3], locals(), globals())
del module

然后,从你的代码这样做:

import Foo

您现在可以使用

Foo.bar
Foo.eggs
Foo.spam

从Foo导入*不是一个好主意,有几个原因,包括名称冲突,使其难以分析代码。

其他回答

将__all__变量添加到__init__.py,包含:

__all__ = ["bar", "spam", "eggs"]

参见http://docs.python.org/tutorial/modules.html

我也遇到过这个问题,这是我的解决方案:

import os

def loadImports(path):
    files = os.listdir(path)
    imps = []

    for i in range(len(files)):
        name = files[i].split('.')
        if len(name) > 1:
            if name[1] == 'py' and name[0] != '__init__':
               name = name[0]
               imps.append(name)

    file = open(path+'__init__.py','w')

    toWrite = '__all__ = '+str(imps)

    file.write(toWrite)
    file.close()

这个函数创建一个名为__init__.py的文件(在提供的文件夹中),其中包含一个__all__变量,该变量保存文件夹中的每个模块。

例如,我有一个名为Test的文件夹 它包含:

Foo.py
Bar.py

所以在脚本中,我想把模块导入,我会写:

loadImports('Test/')
from Test import *

这将从Test中导入所有内容,Test中的__init__.py文件现在将包含:

__all__ = ['Foo','Bar']

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

我有一个嵌套的目录结构,即在包含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)

也许这不是实现这一目标的最佳方式,但除此之外我没有别的办法。

只需通过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