【问题标题】:AttributeError: module A has no attribute BAttributeError:模块 A 没有属性 B
【发布时间】:2021-12-01 23:46:14
【问题描述】:

又一个 python 导入问题。

我有一个目录结构

thing
  |- __init__.py
  |- run.py
  |- mod
      |- __init__.py
      |- what
           |- __init__.py
           |- yo.py

yo.py的内容是

class Yo:
    def __init__(self):
        print("initialized What")

而我run.py的内容是

from mod.what import yo

y = yo.Yo
print(y)
y()

一切都很好。

<class 'mod.what.yo.Yo'>
initialized What

但我需要像这样导入:

from mod import what

y = what.yo.Yo
print(y)
y()

然后我得到

Traceback (most recent call last):
  File "/Users/pavelkomarov/Desktop/thing/run.py", line 4, in <module>
    y = what.yo.Yo
AttributeError: module 'mod.what' has no attribute 'yo'

为什么?我有__init__.pys 了。 python不应该能够找到类吗?这种结构对我来说很重要,因为我在某个模块下有很多类,并且需要能够全部访问它们,最好不必对每个类进行更精细的导入,这需要大量代码。

【问题讨论】:

  • from mod import what 导入 __init__.py yo.py。这不是导入在 Python 中的工作方式。您需要像这样导入的原因是什么?
  • 所以我需要在__init__.pys 中链接导入语句才能开始工作?我需要像这样导入,因为我不允许使用 * 并且我不希望 100,000 个导入语句后跟 100,000 次使用,而我可以使用稍长的名称进行 100,000 次使用。
  • 天哪,太恶心了。我已经使用 python 近十年了,但我们仍然对基础知识感到困惑,不得不做这些 hack!这是该语言的一个主要弱点,每个人都知道。

标签: python import module


【解决方案1】:

感谢莫里斯和其他线程的人。

我发现了

import importlib
import pkgutil

for mod_info in pkgutil.walk_packages(__path__, __name__ + '.'):
    mod = importlib.import_module(mod_info.name)

    # Emulate `from mod import *`
    try:
        names = mod.__dict__['__all__']
    except KeyError:
        names = [k for k in mod.__dict__ if not k.startswith('_')]

mod__init__.py 中就可以了。如果你把它放在what__init__.py中,它也可以工作。

我不同意这是接近禅的东西,但它确实有效。

【讨论】:

    猜你喜欢
    • 2020-10-14
    • 2018-04-14
    • 2019-02-18
    • 1970-01-01
    • 2020-01-01
    • 2019-07-20
    • 2021-11-05
    • 2021-11-04
    相关资源
    最近更新 更多