2015-09-14 72 views
0

如何打破這個特定的循環導入。我在頂部添加了一個簡單的示例來突出顯示該問題。打破Python的循環導入

module_tit.py

import tat 
class Tit 
    def tit(x): 
     return tat.inst.tat(x) 

inst = Tit() 

if __name__=='__main__: 
    print "tit 12 %s" % inst.tit(12) 

module_tat.py

import tit 
class Tat: 
    def tat(x): 
     if x>0: return tit.inst.tit(x-1) 
     else: return 'bottom' 

inst = Tat() 

if __name__=='__main__: 
    print "tat 5 %s" % inst.tat(5) 
  • 我的代碼的設計,強烈要求山雀和達在自己的模塊。
  • 非常重要的是,tit或tat可能是第一個加載的模塊。
  • 這是可能的python在任何方式?下面===

===原來的問題我有很多幾十個常數等的base_module它是由許多進口, 而且進口什麼。在這裏面我有基礎模塊中的重點班,這取決於一個漂亮的打印機模塊做事情的印刷:

to_str = None 
class Thing_Version1(object): 
    def __repr__(): 
     to_str(self) 

在漂亮的打印模塊,我有:

def to_str(x): 
    ... 
import base_module 
base_module.to_str = to_str 

當漂亮的打印機模塊設置「base_module.to_str」,以便一切正常。這在99%的時間內工作,但在調試器中,它不夠漂亮,無法裝載漂亮的打印機(即使在普通的解釋器中,我的加載過程確實會強制最終加載pprint模塊。動態導入:

class Thing_Version1(object): 
    def __repr__(): 
     import pprint 
     pprint.to_str(self) 

但是這也失敗有時找不到pprint模塊中的「to_str」功能(我假設,因爲循環引用)

我的最終目標是迫使pprint的負荷。隨時加載base_module,並且 允許pprint取決於base_module中的幾十個常量。

這不可能嗎?

+0

我不認爲這與循環引用有關。您應該在基本模塊中導入pprint,因爲這是合同的地方。如果你在本地導入它,那麼導入的對象範圍只在該本地函數中,所以任何想使用'pprint.to_str()'的人都必須'導入pprint'。你必須記住python是動態解析的,所以'x = 0; def p():print(x); x = 1; p()'打印1不是0. – AChampion

+2

你能否給一個[mcve]更好地展示你想要達到的目標?這些常量在哪裏定義了'pprint'要求,爲什麼不將它打包到一個實用程序函數/模塊中供您的項目的其餘部分使用? – jonrsharpe

+0

@achampion pprint必須導入base_module,因爲它有幾十個所需的常量等現在你告訴我動態地執行pprint的導入來打破循環。這聽起來不錯,如果你看看我上面的第二個代碼塊,你會看到我在對象打印過程中有一個動態的pprint導入。這工作99%的時間。有時候pprint模塊將不具有to_str功能。我認爲這發生在一個模塊被循環加載時。例如在執行第一次加載期間,它會導入一個遞歸重新導入它的模塊。我看不出如何避免! –

回答

1

不幸的是我不能重現你的問題。 Python有動態分辨率,以便循環引用很少會成爲問題:

fred.py

import wilma 
count = 4 
def main(): 
    wilma.pr('Hello') 

wilma.py

import fred 
def pr(str): 
    print(str*fred.count) 

的Python REPL

>>> import fred 
>>> fred.main() 
HelloHelloHelloHello 

您是否努力避免在Python中很少發生的問題? 你能提供一個你遇到的問題的最小例子嗎?

+0

在我的每一個模塊中,我通常都會有一個'inst'變量,它將包含一個類(例如打印機)的單例,您經常只使用它。這些'inst'變量的代碼在LOAD時執行。因此,如果它試圖利用其他本身處於動態加載過程中的類的依賴關係,它可能會崩潰。我的目標是在其源代碼所在的類中具有初始化對象,並自動創建它們。但也許這不會發生。 –

+0

我接受你的回答,這是正確的,但我從來沒有設法表達我的實際問題。我的代碼總是在解釋器中運行,但在調試器窗口內打印值時,__repr __()方法未運行。但刪除越來越多的初始化代碼我最終得到它的工作....但我真的不知道內部調試器環境之間有什麼不同。和主要的環境。謝謝 –