[英]python namespace: __main__.Class not isinstance of package.Class
[英]Calling isinstance in main Python module
如果在__main__
空間中使用,則存在異常的異常行為。
請考慮以下代碼
a.py:
class A(object):
pass
if __name__ == "__main__":
from b import B
b = B()
print(isinstance(b, A))
b.py
from a import A
class B(A):
pass
main.py
from a import A
from b import B
b = B()
print(isinstance(b, A))
當我運行main.py
,我按預期得到True
,但是當我運行a.py
,我得到了False
。 看起來A
的名字在那里得到前綴__main__
。
我怎樣才能獲得一致的行為? 我需要這個技巧,在a.py
導入B
,在文件a.py
上運行doctest
。
WSo運行a.py
時會發生什么,Python會讀取a.py
並執行它。 在執行此操作時,它會導入模塊b
,它導入模塊a
,但它不會重復使用先前解析它的定義。 所以現在你在a.py
有兩個定義a.py
,稱為模塊__main__
和a
,因此不同的__main__.A
和aA
。
通常,您應該避免導入正在執行的模塊。 相反,您可以創建一個新文件來運行doctests並使用類似的東西
import a
import doctest
doctest.testmod(a)
並從模塊a
刪除__main__
部分。
事件鏈:
A
class A
語句,在__main__
命名空間中創建A
b
是導入的。 a
是進口的。 class A
語句執行,創建A
在a
命名空間。 此A
在a
命名空間中不具有相對於A
在__main__
比已經由相同的碼生成的其它命名空間。 它們是不同的對象。 我同意赫爾穆特的觀點,即最好避免這種循環進口。 但是,如果您希望使用最少的更改來修復代碼,則可以執行以下操作:
讓我們重命名b.py
- > bmodule.py
所以我們可以區分b
從模塊b
變量(希望您的真實代碼中的這些名字都已經不同):
class A(object):
pass
if __name__ == "__main__":
import bmodule
b = bmodule.B()
print(isinstance(b, bmodule.A))
版畫
True
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.