Python按文件夹模块导入
我有一个目录结构:Python按文件夹模块导入,python,import,Python,Import,我有一个目录结构: example.py templates/ __init__.py a.py b.py a.py和b.py只有一个类,命名与文件相同(因为它们是cheetah模板)。出于纯粹的风格原因,我希望能够在example.py中导入和使用这些类,如下所示: import templates t = templates.a() 现在,我在模板文件夹的\uuu init\uuuu.py中使用它来实现这一点: __all__ = ["a", "b"] from
example.py
templates/
__init__.py
a.py
b.py
a.py
和b.py
只有一个类,命名与文件相同(因为它们是cheetah模板)。出于纯粹的风格原因,我希望能够在example.py
中导入和使用这些类,如下所示:
import templates
t = templates.a()
现在,我在模板文件夹的\uuu init\uuuu.py
中使用它来实现这一点:
__all__ = ["a", "b"]
from . import *
from a import *
from b import *
但是,这看起来很糟糕(可能是多余的),甚至不能满足我的要求,因为我必须使用这样的类:
t = templates.a.a()
想法?在您的
\uuuuu init\uuuuuuuupy
中:
__all__ = ["a", "b"]
from . import *
from a import *
from b import *
现在所有
a
的内容都将在模板中,所有b
的内容也将在模板中。我甚至不知道您可以从中获得。导入*
。我的python解释器抱怨这样的语句。不过,对于您的问题,您可以:
# __init__.py
from . import a, b
a = a.a
b = a.b
您现在可以使用
# example.py
import templates
t = templates.a()
其他解决方案:
# __init__.py
from a import *
from b import *
为了避免从导入中重复*
25次,您需要一个循环,例如:
import sys
def _allimports(modnames)
thismod = sys.modules[__name__]
for modname in modnames:
submodname = '%s.%s' % (thismod, modname)
__import__(submodname)
submod = sys.modules[submodname]
thismod.__dict__.update(submod.__dict__)
_allimports('a b c d e'.split()) # or whatever
我将有意义的代码放在函数中,因为(a)它总是最好的[[为了性能和避免污染模块的名称空间],(b)在这种特殊情况下,它也避免了事故(例如,某些子模块可能会定义一个名称thismod
或modnames
…因此,将我们在循环中使用的那些名称保持在函数的本地非常重要,而不是模块全局,这样它们就不会被意外践踏;-)
如果要强制执行名为modname
的模块只有一个具有相同名称的类(或其他全局类),请将循环的最后一条语句更改为:
setattr(thismod, modname, getattr(submod, modname))
“from.import…”是一个相对的导入,这通常不是一个很好的主意。有没有一种方法可以做到这一点,每个都没有一行呢?我实际上有25个模板。我非常喜欢简单。我不介意每次添加另一个模块时都在init.py中添加一行。你的品味可能会有所不同……谢谢!有没有关于我正在尝试做的/我现在拥有的是否是g的想法好主意吗?@colinmarc,我同意你对在生产代码中使用这种(深度的)内省/(轻微的)元编程持怀疑态度,但在这里你真的没有太多的选择——类为a
的a.py
&c文件(我相信)给一只猎豹,要求用户总是从模板导入(&c),然后使用a。a()
(&c)确实觉得有点多余(我可能会这么做,但这只是因为我是一个“总是导入模块——从不导入包,从不从模块内部导入任何东西”的传道者,而且是导入*
…-)的死敌--大多数人更合理!-@colinmarc,当然,如果您可以将所有类放在template.py
中,而不是当前的template
目录/包中,那会简单得多。