当前位置: 首页 > 知识库问答 >
问题:

相对导入不起作用,看起来找不到模块

秦博达
2023-03-14

我有以下情况,其中a是目录:

a/
  __init__.py
  first.py
  second.py
print('i\'m starting the directory')
__all__ = ['second', 'first']
print('hi, i\'m the first')
from . import *
print('hi, i\'m the second')

所以当我从交互式提示中运行时:

>>> import a.first
i'm starting the directory
hi, i'm the first
hi, i'm the second
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/antox/Scrivania/a/first.py", line 2, in <module>
    from . import *
AttributeError: 'module' object has no attribute 'first'

为什么它没有找到第一个。py模块?我的意思是我希望没有错误;在导入运行期间,我认为它可以看到第一个。py已经加载,所以没有错误,它只是跳到__all__中列出的下一个。

共有1个答案

邵逸明
2023-03-14

这似乎是Python导入机制中的一个长期存在的bug。问题是a模块直到完全加载后才被添加到其包的全局命名空间中。如果module仅部分加载,则将与包导入module语句断开。不过,您仍然可以使用import package.module,长期以来,导入系统对此提供了特殊支持。

正如jonrsharpe评论的那样,Python开发人员从2004年起就意识到了这个问题。由于只有当存在涉及包中模块的循环导入时才会出现这个问题,而循环导入通常被认为是糟糕的设计,所以他们没有把修复它放在非常高的优先级上。

然而,最近有了进展!几个月前为Python 3.5添加了一个部分修复程序,它刚刚发布了第一个alpha版本(完整版本定于9月发布)。在加载package时,修复程序实际上并没有将module添加到package,而是将一个额外的检查添加到from package import module语句,以便这些语句在以前引发imporder的循环导入情况下工作。

但是,这并不能修复from package import*的情况。通配符导入的代码显然仍然希望包中的所有名称。__all__实际存在于模块本身中。它似乎没有检查sys.modules字典来检查仍在加载过程中的模块。

那么,这对您的代码意味着什么呢?我认为有两个重要的教训:首先,如果可以的话,不要使用循环导入(而是尝试将两个模块中的一些代码分解到第三个实用工具模块中)。其次,不要使用通配符导入(如果first.py使用from.import first,Second,在Python 3.5中不会出现错误)。

 类似资料:
  • 问题内容: 我似乎无法让绝对导入在python中工作。这是我的文件结构: foo.py: 我反而得到: 这到底是怎么回事?我觉得我缺少基本的东西。尽管这个例子很简单,但我需要绝对导入才能为实际项目工作,因此仅用相对导入替换导入是不可行的。我正在使用python 2.7.13 预先感谢您的任何见解! 问题答案: 由于未显示,因此我必须假设您正在运行,这会将脚本()的目录放在开始的位置,而实际上您希望

  • 我似乎无法让绝对导入在python中工作。以下是我的文件结构: 福。py: 我反而得到: 这到底是怎么回事?我觉得我错过了一些基本的东西。虽然这个例子很简单,但我需要绝对导入来为实际项目工作,因此仅用相对导入替换导入是不可取的。我正在使用python 2.7。13 这里列出的解决方案都没有帮助 提前感谢您的任何见解!

  • 这可能是个愚蠢的问题,但我无论如何也无法解决。我有一个JavaScript文件,其中包含我想要导出的各种函数。 当我调用这个方法(使用mocha)时,我得到一条错误消息“export function AddNumbers(…numbers)Unexpected token export”。该项目构建为ES6。有人知道我做错了什么吗? 最好的问候,托斯顿

  • 对于以下代码: C++14编译器产生错误: 我很好奇为什么模板参数推导在这里不起作用。似乎,假定g的参数是int类型,我们可以推断f的参数是类型,因此f中的。为什么没有发生这种情况?我对C++标准中解释这一点的相关部分很感兴趣。T是否出现在这里的非推导上下文中? 因此,创建非推导上下文的不是尖括号。

  • 问题内容: 我正在使用Solr 4.2。请注意,完全导入有效,但增量导入却不起作用。增量导入不会产生任何错误,但不会获取任何更改。这是数据配置文件。 这是我没有运气的尝试。 将p.product_id =’$ {dih.delta.product_id}更改为p.product_id =’$ {dih.delta.id}以及其他方式。将updtime>’$ {dih.last_index_time

  • 我是Java新手,正在努力学习。我目前陷入困境,不知道为什么无法从文件夹导入。