【问题标题】:How to resolve this import error in Python 3.6? [duplicate]如何解决 Python 3.6 中的这个导入错误? [复制]
【发布时间】:2019-10-17 01:26:33
【问题描述】:

我有一个very simple namespace package(包括下面的内容,以及目录布局)。如果我尝试导入 namespace_repro.module,则会收到以下错误:AttributeError: module 'namespace_repro' has no attribute 'module'。据我了解,我的包具有有效的布局,并且导入应该可以工作。有趣的是,该错误仅在 Python 3.6.8 中存在,并且在 Python 3.7 中导入成功。

如何重现问题?

我有一个名为import-error-repro 的目录,其中包含一个setup.py(见下文),然后是一个嵌套目录路径src/namespace_repro/module,包含三个文件__init__.pyx.pyy.py。他们的内容:

setup.py

from setuptools import find_namespace_packages, setup

setup(
    name='namespace-repro',
    version='0.1.0',
    python_requires='>=3.6',
    packages=find_namespace_packages('src'),
    package_dir={'': 'src'},
    zip_safe=False,
)

src/namespace_repro/module/__init__.py:

from namespace_repro.module.x import x

src/namespace_repro/module/x.py:

import namespace_repro.module.y as y

x = y.y

最后是src/namespace_repro/module/y.py:

y = True

我通过conda create -n namespace6 python=3.6 ipython 创建了一个全新的 Python 3.6 conda 环境,然后我激活它并将包安装为pip install -e ./import-error-repro(注意-e 无关紧要,没有它问题是可重现的)。之后,我在ipython 中尝试了import namespace_repro.module(尽管在官方python 解释器中也发生了同样的情况)。结果是

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-1-bcae5a697dad> in <module>
----> 1 import namespace_repro.module

~/namespace-repro/src/namespace_repro/module/__init__.py in <module>
----> 1 from namespace_repro.module.x import x

~/namespace-repro/src/namespace_repro/module/x.py in <module>
----> 1 import namespace_repro.module.y as y
      2 
      3 x = y.y

AttributeError: module 'namespace_repro' has no attribute 'module'
---------------------------------------------------------------------------

奇怪的是,导入系统两次找到namespace_repro.module,第三次却失败了!

其他一些有趣的行为:

In [1]: import namespace_repro.module.y as y  # This doesn't work.
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-4035347ea59b> in <module>
----> 1 import namespace_repro.module.y as y

AttributeError: module 'namespace_repro' has no attribute 'module'

In [2]: import namespace_repro.module.y  # But this one does! Why?

In [3]: dir(namespace_repro.module.y) # The error returns when we actually want to use the module.
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-d89bcfd9e509> in <module>
----> 1 dir(namespace_repro.module.y)

AttributeError: module 'namespace_repro' has no attribute 'module'

In [4]: from namespace_repro.module.y import y  # This works fine!

In [5]: y
Out[5]: True

目录布局

. import-error-repro
+-- setup.py
+-- src
|   +-- namespace_repro
|   |   +-- module
|   |   |   +-- __init__.py
|   |   |   +-- x.py
|   |   |   +-- y.py

【问题讨论】:

  • 我也有同样的问题。这种导入问题只发生在 python 3.6.x 上。在 3.7 上工作的相同代码在任何 3.6 版本中都失败。没有人知道这个版本是怎么回事?
  • 你说得对,我不知道这行得通。我不知道你的问题。
  • module/* 中的代码是错误的,所以它永远不会被导入并且属性模块不会在命名空间中创建。使用从 .导入 y 和 from 。 import x 和 import 就会成功
  • 这是issue #30024,在 Python 3.7.0 中已修复。另请参阅副本,其中也详细介绍了这一点。解决方法是使用import namespace_repro.module.y,然后使用y = namespace_repro.module.y,或者使用from namespace_repro.module import y
  • 发生的情况是 sys.modules['namespace_repro']sys.modules['namespace_repro.module'] 仍处于“导入”状态,并且还没有设置必要的属性(还没有 sys.modules['namespace_repro'].module,因为 sys.modules['namespace_repro.module']仍在处理中),但 import ... as ... 机制依赖于已设置的这些属性。

标签: python python-3.x python-import namespace-package


【解决方案1】:

这是 CPython 错误 30024,不出所料,它已在 3.7 中得到修复。请注意,自 3.5 以来,具有相对(循环)导入的更惯用的形式一直有效。

【讨论】:

  • 是的,这就是我将其作为副本关闭的原因。你刚从电线下面进来,但赏金已经消失了,抱歉。
  • @MartijnPieters:没问题。这似乎很模糊,我什至没有想过要寻找重复。
猜你喜欢
  • 2022-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多