python包导入细节_python循环导入是一个实现细节吗?
從一個小的研究中,聽起來答案似乎是,涉及到一些規(guī)范和未文檔化的行為,這些行為與模塊如何初始化以及import語句的不同形式如何解析(sub)模塊有關(guān)。總的來說,循環(huán)導(dǎo)入的行為看起來應(yīng)該由系統(tǒng)很好地定義,但是您看到的行為是“一種實現(xiàn)怪癖”。1
雖然我沒有詳細研究Python的導(dǎo)入系統(tǒng)的規(guī)則,但是我能夠深入了解您所觀察到的特定問題。在
為了達到這個目的,我首先注意到,python3.7中代碼的行為發(fā)生了變化:它現(xiàn)在只打印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.)
關(guān)于導(dǎo)致變更的Python問題的討論包含了一些關(guān)于之前發(fā)生的事情的討論,以及一些鏈接,這些鏈接指向先前討論的3.7之前的行為為什么會起作用。我發(fā)現(xiàn)一些評論和鏈接在這里特別有用:
第一條注釋解釋了您觀察到的行為(this Stack Overflow answer討論了相同錯誤在類似情況下是如何發(fā)生的):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激發(fā)了對“[c]circular imports including relative imports”in Python 3.5的支持。這就是我對
更一般地說,對于您的答案,this comment(來自Guido自己)聲明循環(huán)導(dǎo)入的行為是由定義的: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.
基于“循環(huán)”、“循環(huán)”或其任何明顯變體都不出現(xiàn)在the documentation for the import system中的事實,我假設(shè)有關(guān)循環(huán)導(dǎo)入的規(guī)則雖然一致,但卻是系統(tǒng)的涌現(xiàn)屬性,而不是顯式行為。在
(注意,導(dǎo)入系統(tǒng)的文檔也沒有提到3.7中的更改,也沒有提到任何關(guān)于import ... as ...或{
python3.8中也有一個小的變化,盡管它似乎沒有出現(xiàn)在the changelog中。在
如果取消了othermodule中的submod.notyetdefined()注釋,Python 3.6和3.7都會引發(fā)以下錯誤: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當(dāng)前模塊是否在訪問丟失的屬性時被初始化的結(jié)果;它實際上并不執(zhí)行與循環(huán)導(dǎo)出相關(guān)的任何操作,除非知道它們是模塊的未定義屬性在初始化時可能被訪問的最可能原因。在
具有諷刺意味的是,這句話來自于this email,這是bpo-30024討論中給出的,作為bpo-17636引起的變化的基本原理,他們修復(fù)了一個案例,但卻保留了另一個案例,這就是導(dǎo)致您錯誤的原因。在
總結(jié)
以上是生活随笔為你收集整理的python包导入细节_python循环导入是一个实现细节吗?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 源码安装mysql主从_mysql源码安
- 下一篇: websocket python爬虫_p