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

25

我有一个文件夹,里面有多个包含各种类的文件。这些类都可以在一个大文件中,但为了使其更易于阅读,我将其拆分成多个文件,具体取决于类属于哪个部分。

我想要将文件夹中所有文件中的所有类导入到__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

但我希望它可以获取文件夹中的所有文件,而不必显式指定(这样文件可以被倒入,然后使用)。

是否有任何方法可以实现这一点?


3
不好的想法。让文件被倒入那里,然后使用。 - Lennart Regebro
正如abarnert所暗示的那样,这是因为您想要制作插件吗? - Lennart Regebro
4个回答

8
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

2
这是一个非常糟糕的想法。如果您想添加文件“转储并使用”的机制,那么您可能需要设计一个插件方案,并显式搜索插件目录。
通常的做法是使用os.listdir或者os.walk在一个或多个插件目录上进行迭代,然后对于每个Python文件,使用importlib(或Python 2.x中更低级别的imp等效项)按路径导入它。
但是,如果您真的坚持要在包内部以这种方式模拟事物,那么可以在__init__.py文件中使用os.path.dirname(__file__)作为插件目录,使用基本相同的技巧。
如果您坚持执行from foo import *而不是通过路径导入import foo的等效操作,那么这同样很容易 - 或者,您可以使用execfile
如果您不知道如何执行这些简单的操作,或者不知道如何在文档中查找它们...那么您绝对不应该尝试这样做。所以,在这种情况下,我不会提供示例代码。

-1

没有,而且除此之外,你不应该使用import *,而是在__init__.py中明确地导入。顺便说一下,这种模块分割的方式很常见,也是一个好的实践。

如果每个模块中都定义了__all__属性,则可以接受import *,但这样做没有真正的好处,而且容易破坏代码分析器。


1
不,没有这样做过:嗯,实际上,我曾经这样做过一次...然后又撤销了<g> - 正如你所提到的,从维护的角度来看,这是一个非常糟糕的想法。 - bruno desthuilliers
当然有方法(或许很多)。任何事情都是可能的。但并不容易,也不推荐这样做。 :-) - Lennart Regebro

-1

显式优于隐式。不要这样做。你肯定可以编写一些自动导入的代码,但真的不值得。只需在__init__.py中每个添加的文件加一行代码就可以了。简单的解决方案总是更好的,除非你从更复杂的问题中获得了很多收益,但在这里肯定不是这种情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接