python迴圈引用的處理

2021-10-07 04:38:04 字數 2228 閱讀 2423

假設同一資料夾下存在三個檔案:a.py, b.py 和run.py

a和b中定義a,b,c類,run.py執行呼叫

a中定義類a和c,b中定義類b,其中b是a的子類,c是b的子類,

因此b.py中需要import a,a.py中需要import b,造成迴圈引用

檔案內容分別如下(報錯版):

a.py

from b import b

classa:

name =

'a'def

print_self

(self)

:print

(self.name)

class

c(b)

: name =

'c'c = c(

)c.print_self(

)

b.py

from a import a

class

b(a)

: name =

'b'

run.py

from a import a, b, c

test_a = a(

)test_b = b(

)test_c = c(

)test_a.print_self(

)test_b.print_self(

)test_c.print_self(

)

執行run.py,執行結果:

結果說明:

run.py中執行from a import a, b, c時,由於a.py中的b是從b.py中import過來的,

會到b.py中執行**,遇到第一行from a import a,又回到a.py中執行from b import b,造成無限迴圈,編譯器報錯。

那怎麼處理呢?

注意到b繼承自a,c繼承自b,我們可以在需要使用到b時再import b,也即把a.py修改如下(正確執行版):

classa:

name =

'a'def

print_self

(self)

:print

(self.name)

from b import b

class

c(b)

: name =

'c'c = c(

)c.print_self(

)

執行結果:

1.第乙個"c"由a.py中c.print_self()輸出

2."a"由run.py中test_a.print_self()輸出

3."b"由run.py中test_b.print_self()輸出

4.第二個「c」由run.py中test_c.print_self()輸出

執行順序:

1.from a import a, b, c時,會把a.py中的**執行一遍

2.首先宣告class a

3.執行到第8行from b import b,到b.py中,執行from a import a,由於a已經被宣告,在這裡返回乙個a的引用,給b作父類(這是由於python編譯器把每個模組都視為單例,已經import的模組便不再import,只是在b.py中建立乙個a類的引用,供b類的宣告與初始化)。

4.回到a.py中宣告c,初始化c,執行c.print_self(),輸出第乙個"c"

5.a.py走完一遍,a,b,c均已宣告,from a import a, b, c返回a,b,c三個類的引用

6.run.py繼續往下執行,完成三個類的初始化與方法呼叫,依次輸出「a」,「b」,「c」

以上為能解釋現象的執行順序,僅供參考,是否正確,需要到python原始碼中找解答

---------------------------------update---------------------------------

上述方案能執行,但理解上是不正確的,因為直接執行a.py也報錯:

迴圈引用的處理

迴圈引用 兩個類互相引用,導致單純互相引用標頭檔案,編譯無法通過。解決方案 首先,要理解宣告和實現之間的差別。宣告只需要在使用類的前面新增class 而實現是包含具體成員函式和變數的類。如例1.class a class b 1.此時可在a的前面宣告class b,就可以使用b了。在b中只需要正常引...

Python迴圈引用的解決方案

1.延遲匯入 即將 from import yyy 放到函式或類的內部,從而使其作用域變成區域性的,但是這樣可能會對效能有些影響 2.將 from import yyy 轉換成 import yyy 的形式 3.以上兩種方式都是治標不治本的,只能說能夠用,但是並不符合規範,最好的辦法應該是從 布局入...

Python中迴圈的跳躍處理

python中的for迴圈是不允許改變迭代程序的,看下面的例子 wordlist 1 2 3 4 5 6 7 8 9 10 i 0for i in range len wordlist print wordlist i i 3然後輸出結果是 123 4567 8910這是因為在python的for迴...