python包导入细节_python循环导入是一个实现细节吗?
從一個小的研究中,聽起來答案似乎是,涉及到一些規范和未文檔化的行為,這些行為與模塊如何初始化以及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引起的變化的基本原理,他們修復了一個案例,但卻保留了另一個案例,這就是導致您錯誤的原因。在
總結
以上是生活随笔為你收集整理的python包导入细节_python循环导入是一个实现细节吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 源码安装mysql主从_mysql源码安
- 下一篇: tkinter使用MySQL存数据_我无