导入文件夹中所有文件中的所有类(或函数),就好像它们都在__init__文件中一样

时间:2013-05-28 09:22:16

标签: python python-import

我有一个包含许多不同类的多个文件的文件夹。这些都可以放在一个大文件中,但是为了让它更容易阅读,我将它分成多个文件,具体取决于类的属性。

我想将文件夹中所有文件的所有类导入__init__文件,以便我可以从文件夹导入任何内容,而不知道它属于哪个文件。

示例:

/kitchen
 + __init__.py
 + fridge.py
 + stove.py
 + cupboard.py

现在我必须做

from kitchen.fridge import milk

当我想做的时候

from kitchen import milk

相当于我可以在__init__.py执行:

from kitchen.fridge import *
from kitchen.stove import *
from kitchen.cupboard import *

然后我可以做

from kitchen import milk

但是我希望它能够获取文件夹中的所有文件而不必明确指定它(这样文件可以转储到那里然后使用)。

有没有办法做到这一点?

4 个答案:

答案 0 :(得分:4)

这是一个非常糟糕的主意。如果你想为“转储并使用”文件添加一种机制,你可能想要提出一个插件方案,并明确搜索插件目录。

通常这样做的方法是使用os.listdiros.walk迭代一个或多个插件目录,然后,对于每个Python文件,使用importlib(或更低级别的等效项) {2.}},在Python 2.x中按路径导入它。

但是,如果你真的坚持在包中做这样的事情,你可以在imp文件中基本上使用__init__.py作为插件目录。

而且,如果您真的坚持按路径执行相当于os.path.dirname(__file__)而不是from foo import *的操作,那就非常简单 - 或者,您可以使用import foo

如果您不知道如何做这些简单的事情,或者如何在文档中查找它们......那么您绝对不应该尝试这一点。因此,在这种情况下,我不会提供示例代码。

答案 1 :(得分:2)

明确比隐含更好。不要这样做。你当然可以在一定程度上破解自动导入的东西。但这真的不值得。在__init__.py中,每个添加的文件只需要一个额外的行,您就完成了。简单的解决方案更好,除非你从更复杂的解决方案中获得很多,这当然不是这种情况。

答案 2 :(得分:0)

不,没有。除此之外,您不应import *,而应明确导入__init__.py。顺便说一下,这种分割模块的方法很常见,也很好。

如果你还在每个模块中定义了一个import *属性,那么

__all__是可以接受的,但这样做并没有真正的好处,并且它往往会破坏代码分析器。

答案 3 :(得分:0)

import os, sys

dir_path = os.path.dirname(os.path.abspath(__file__))
files_in_dir = [f[:-3] for f in os.listdir(dir_path)
                if f.endswith('.py') and f != '__init__.py']
for f in files_in_dir:
    mod = __import__('.'.join([__name__, f]), fromlist=[f])
    to_import = [getattr(mod, x) for x in dir(mod)]
               # if isinstance(getattr(mod, x), type)]  # if you need classes only

    for i in to_import:
        try:
            setattr(sys.modules[__name__], i.__name__, i)
        except AttributeError:
            pass