python包导入细节_python循环导入是一个实现细节吗?

本文探讨了Python中循环导入的问题,特别是在涉及子模块绑定名称的情况下。文章深入分析了Python 3.7版本中对循环导入支持的改进,并回顾了相关变更的历史背景及背后的技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从一个小的研究中,听起来答案似乎是,涉及到一些规范和未文档化的行为,这些行为与模块如何初始化以及import语句的不同形式如何解析(sub)模块有关。总的来说,循环导入的行为看起来应该由系统很好地定义,但是您看到的行为是“一种实现怪癖”。1

虽然我没有详细研究Python的导入系统的规则,但是我能够深入了解您所观察到的特定问题。在

为了达到这个目的,我首先注意到,python3.7中代码的行为发生了变化:它现在只打印OK。来自the changelog for Python 3.7的这一点说明了为什么:Circular imports involving absolute imports with binding a submodule to a name are now supported. (Contributed by Serhiy Storchaka in bpo-30024.)

关于导致变更的Python问题的讨论包含了一些关于之前发生的事情的讨论,以及一些链接,这些链接指向先前讨论的3.7之前的行为为什么会起作用。我发现一些评论和链接在这里特别有用:

第一条注释解释了您观察到的行为(this Stack Overflow answer讨论了相同错误在类似情况下是如何发生的):The background here is the change in http://bugs.python.org/issue17636 that allows IMPORT_FROM to fall back to sys.modules when written as "from a.b import c as m", while the plain LOAD_ATTR generated for "import a.b.c as m" fails.

注意,bpo-17636激发了对“[c]circular imports including relative imports”in Python 3.5的支持。这就是我对

更一般地说,对于您的答案,this comment(来自Guido自己)声明循环导入的行为是由定义的:The semantics of imports in the case of cycles are somewhat complex but clearly defined and there are only a few rules to consider, and from these rules it is possible to reason out whether any particular case is valid or not.

基于“循环”、“循环”或其任何明显变体都不出现在the documentation for the import system中的事实,我假设有关循环导入的规则虽然一致,但却是系统的涌现属性,而不是显式行为。在

(注意,导入系统的文档也没有提到3.7中的更改,也没有提到任何关于import ... as ...或{

python3.8中也有一个小的变化,尽管它似乎没有出现在the changelog中。在

如果取消了othermodule中的submod.notyetdefined()注释,Python 3.6和3.7都会引发以下错误:AttributeError: module 'package.submodule' has no attribute 'notyetdefined'

在Python 3.8.0b4中,将生成以下更有用的消息:AttributeError: partially initialized module 'package.submodule' has no attribute 'notyetdefined' (most likely due to a circular import)

此消息似乎是simple check当前模块是否在访问丢失的属性时被初始化的结果;它实际上并不执行与循环导出相关的任何操作,除非知道它们是模块的未定义属性在初始化时可能被访问的最可能原因。在

具有讽刺意味的是,这句话来自于this email,这是bpo-30024讨论中给出的,作为bpo-17636引起的变化的基本原理,他们修复了一个案例,但却保留了另一个案例,这就是导致您错误的原因。在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值