Python模塊的交叉引用(導入循環)問題分析

  • 2020 年 2 月 11 日
  • 筆記

    實際項目中遇到python模塊相互引用問題,查資料,終於算是弄明白了。

    首先交叉引用或是相互引用,實際上就是導入循環,關於導入循環的詳細說明,可見我摘自《python核心編程》第二版的摘抄:Python導入循環方法

    附錄給了一種解決交叉引用的方法,試了,不行,但關於交叉引用問題本身說明的很清楚,如果不清楚什麼是交叉引用,可看附錄一。

    循環引用在python圈關注的並不多,語言上沒有提供防止循環依賴的機制。      總的來說,應該在總體結構上避免模塊之間互相依賴,即:A依賴B,B就不要依賴A,這也是代碼重構的一個目標。      對於緊急情況,往往來不及對代碼大動。      只要找到導致循環引用的模塊(最少兩個),把引用關係搞清楚,把某個模塊讓它在真正需要的時候再導入(一般放到函數裏面),或者放到代碼的最後導入,這樣就可以基本解決模塊循環依賴的問題。 

一個小竅門:      查看循環引用的報錯棧時,會找到兩次導入同一個模塊的文件。注意在這個附近找。

總結:

    在python開發過程中,應盡量避免導入循環(交叉引用),但是,如果你開發了大型的 Python 工程, 那麼你很可能會陷入這樣的境地。

一些比較靠譜的方法是:

        1. 把 import 語句放到方法定義的後面。

        2. 將 import 語句移到函數的內部,只有在執行到這個模塊時,才會導入相關模塊。

附錄:

一:Python模塊的交叉引用問題 解讀: How can I have modules that mutually import each other? 有下面兩個文件相互引用,Python解釋器報錯。 foo.py: from bar import bar_var foo_var=1 bar.py: from foo import foo_var bar_var=2 import foo會產生如下錯誤: >>> import foo Traceback (most recent call last):   File "<stdin>", line 1, in ?   File "foo.py", line 1, in ?     from bar import bar_var   File "bar.py", line 1, in ?     from foo import foo_var ImportError: cannot import name foo_var >>> 但並非是因為交叉引用而報錯,而是引用不存在! 導入一個模塊時,發現已經導入,就不會再做一次導入。 from foo import foo_var 相當於運行foo.py, 然後令foo_var = foo.foo_var 這句會發現foo已經導入,但是foo_var=1還沒有執行到, 所以bar.foo_var = foo.foo_var就會出錯。 解決辦法就是不要全局導入,可改為局部作用域內導入。 如果將from XXX import YYY改為import XXX就不會有上述錯誤了。

參考:

http://blog.csdn.net/jq0123/article/details/1527148

http://www.douban.com/group/topic/43938606/

《python核心編程》第二版,導入循環