【问题标题】:Attribute error when module imports itself - works on some computers模块导入时出现属性错误 - 在某些计算机上有效
【发布时间】:2021-07-19 23:19:47
【问题描述】:

我继承了一些我正在尝试运行的 python 脚本。其中包括一些自定义模块,在导入其中一个时出现错误,这似乎是由于其中一个模块自行导入所致。我觉得奇怪的是它可以在一台计算机上运行,​​但不能在另一台计算机上运行。

目录结构如下:

/path/to/packages/python_packages/x
                              |
/path/to/packages/python_packages/x/mod1.py
/path/to/packages/python_packages/x/mod2.py
/path/to/packages/python_packages/x/mod3.py

我添加(并使用 print(sys.path) 进行交叉检查)路径如下:

sys.path.append("/path/to/packages/python_packages/")

然后我做:

import x.mod1 as mod1
import x.mod2 as mod2
import x.mod3 as mod3

导入 mod1 有效。

导入 mod2 不起作用:

AttributeError: module 'x' has no attribute mod2

Traceback 抱怨这一行,出现在 mod2.py 中:

import x.mod2 as mod2

导入mod3不起作用,因为它需要导入mod2,它的方法与上面相同。

在 ipython 的回溯中,我可以看到它找到了正确的 python 文件,因为它从文件中打印出代码及其名称、完整路径。

我已尝试删除所有 init.py 和 pycache。

我尝试在另一台计算机上运行它,在那里我可以毫无问题地导入模块。

在有问题的计算机上,我有 Python 3.6.8,在 CentOS7 (3.10.0-1160.21.1.el7.x86_64) 上运行,在它工作的计算机上,我有 Python 3.9.2,在Manjaro (5.4.108-1-MANJARO)。

我在有问题的计算机上没有 root 访问权限。

完整的回溯如下(我更改了路径和文件名以与上面的解释保持一致):

In [9]: import x.mod2 as mod2

AttributeError                            Traceback (most recent call last)
<ipython-input-9-8c4b062c2395> in <module>
----> 1 import x.mod2 as mod2

/path/to/packages/python_packages/x/mod2.py in <module>
  2 import numpy  as np
  3 
----> 4 import x.mod2 as mod2
  5 
  6 

AttributeError: module 'x' has no attribute 'mod2'

【问题讨论】:

  • 为什么模块需要自己导入?
  • @aaron 它导入自身以访问从它所在位置向上一级的路径。 reference_path = "/".join(mod2.__file__.split("/")[0:-2]+["reference/"])
  • 将其更改为硬编码路径并删除自导入可以解决该问题,但我宁愿保留代码原样并解决任何禁止自导入的问题。
  • @a20 你应该可以直接使用__file__。
  • @aaron 非常感谢!效果很好,据我所知,在我的情况下就足够了。但是,为了社区的利益,我将保留这个问题。自导入应该可以正常工作,就像在其他计算机上一样。

标签: python python-import python-module


【解决方案1】:

没有必要只为了访问mod2.__file__而导入mod2,因为它也可以作为__file__使用。

你应该使用pathlib,而不是字符串摆弄:

reference_path = Path(__file__).absolute().parents[2] / "reference"

不要使用as,而是使用from:

from x import mod1

或者,因为您已经在同一个包中:

from . import mod1

【讨论】:

    【解决方案2】:

    它自己导入是为了访问它所在位置上一级的路径。
    reference_path = "/".join(mod2.__file__.split("/")[0:-2]+["reference/"])

    你应该可以直接使用__file__。

    【讨论】:

      猜你喜欢
      • 2013-07-03
      • 1970-01-01
      • 2021-10-24
      • 2015-04-05
      • 2014-01-29
      • 1970-01-01
      • 2022-11-30
      • 2023-03-26
      • 2019-07-09
      相关资源
      最近更新 更多