我有一个包含许多不同类的多个文件的文件夹。这些都可以放在一个大文件中,但是为了让它更容易阅读,我将它分成多个文件,具体取决于类的属性。
我想将文件夹中所有文件的所有类导入__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
但是我希望它能够获取文件夹中的所有文件而不必明确指定它(这样文件可以转储到那里然后使用)。
有没有办法做到这一点?
答案 0 :(得分:4)
这是一个非常糟糕的主意。如果你想为“转储并使用”文件添加一种机制,你可能想要提出一个插件方案,并明确搜索插件目录。
通常这样做的方法是使用os.listdir
或os.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