【问题标题】:Import all classes in directory?导入目录中的所有类?
【发布时间】:2011-06-05 22:56:08
【问题描述】:

我找到了this,但这不是我想做的。

我想导入一个目录中所有文件中的所有类。基本上,我想替换这个:

from A import *
from B import *
from C import *

有了一些动态的东西,这样我就不必在每次添加另一个文件时都继续编辑我的__init__.py。


glob 解决方案似乎相当于

import A
import B
import C

这根本不一样。

【问题讨论】:

  • 你想用这个实现什么?
  • 这个答案有什么问题:stackoverflow.com/questions/1057431/…?
  • @Ignacio:你说的没有道理。为什么?少打字。不易出错。不要忘记更新文件。节省时间。我真的需要证明这一点吗?
  • @Ignacio:不,没有插件。它不应该像您将文件放入其中以包含插件的地方。一切都将由我建造。我有一大堆类,我把它们都分成单独的文件。该框架需要在启动时将它们全部加载,以便知道它们存在,而且它还使我可以轻松地使用它们,而不必一直导入十几个不同的东西。
  • @AJ/Greg:也许吧。但他们是班级。除非它们被执行,否则它们不太可能引入细微的错误。

标签: python


【解决方案1】:

您可以这样做,但请记住 isinstance(cls, type) 仅适用于新式类。

import os, sys

path = os.path.dirname(os.path.abspath(__file__))

for py in [f[:-3] for f in os.listdir(path) if f.endswith('.py') and f != '__init__.py']:
    mod = __import__('.'.join([__name__, py]), fromlist=[py])
    classes = [getattr(mod, x) for x in dir(mod) if isinstance(getattr(mod, x), type)]
    for cls in classes:
        setattr(sys.modules[__name__], cls.__name__, cls)

【讨论】:

  • 是的,我看到了那个答案,它不起作用。它导入模块,但不导入类。我必须以address.Address 的身份访问该文件,而我只需要Address 就可以访问它。有区别。
  • 你应该使用os.path.join(os.path.dirname(__file__), '*.py')而不是os.path.dirname(__file__) + "/*.py"。
  • @Mark 调整了我的答案以反映这一点。
  • @Mark 是的,无论如何都应该使用__name__。再次调整,看看是否适合你。
  • 对我来说,ImportError: No module named ... 出现在 mod = __import__('.'.join([__name__, py]), fromlist=[py])。
【解决方案2】:

假设你的文件结构如下:

/Foo
    A.py
    B.py
    C.py

要一次全部导入,您需要在要从中导入所有内容的目录中创建__init__.py 文件,其中包含以下代码:

__all__ = ['A', 'B', 'C']

这是更改后的文件结构:

/Foo
    A.py
    B.py
    C.py
    __init__.py

然后,您可以简单地使用:

from Foo import *

【讨论】:

  • 有没有办法避免__init__.py 中的__all__ = ['A', 'B', 'C']?似乎应该有一种更自动的方式将目录中的所有 .py 文件添加到__all__
猜你喜欢
  • 2019-09-05
  • 2014-04-26
  • 2016-10-31
  • 1970-01-01
  • 2019-04-09
  • 2017-04-03
  • 2013-05-27
  • 2017-09-03
  • 2019-09-14
相关资源
最近更新 更多