2013-06-02 59 views
1

我在單個文件中構建了一個相當大的程序。該文件的大小使其無法工作,所以我決定分割成多個模塊,但此後對可變範圍產生了很大的困擾。我已經在很大程度上修正了它(一路上有相當一段時間的學習),但我很想理解好的結構,以避免以後的經驗教訓艱難。有幾個具體的要點,但一般的建議也是受歡迎的。什麼是構建多模塊python程序的最pythonic方法?

模塊需要共享同一個命名空間

我,似乎需要共享同一個命名空間兩個模塊。一個是程序的主要流程(向對象傳輸數據和調用UI),另一個是UI(它響應用戶輸入,調用主流)。

這些模塊中的每一個都應該導入另一個,然後主文件同時導入?這對我來說並不特別優雅。

從[MODULENAME]進口*

在這個問題的答案:

Python: Sharing global variables between modules and classes therein

有是from [modulename] import *應該避免的建議。

可以使用from [modulename] import *來構建一個只有類定義的模塊嗎?什麼是「安全」用例?

+0

爲什麼你認爲你的兩個模塊需要共享相同的命名空間? – BrenBarn

+0

@BrenBarn所以他們可以互相打電話。程序流程功能對數據做了一些處理,這些數據決定了需要呈現給用戶的內容,因此它調用了UI。然後,用戶界面接受用戶的響應,並需要調用程序流程功能來做一些分析/決策。 – user1379351

+0

循環依賴不能在python中工作。當module_a導入module_b時,python沒有經過「import module_b」語句解釋module_a。這意味着您將在module_a中導入後遇到名稱錯誤。這聽起來像你應該堅持一個大文件,或花一些時間重新設計,所以你可以分解出不依賴於任何東西的模塊。 – Seth

回答

1

需要訪問對方名稱空間的模塊與需要共享相同名稱空間的模塊不同。我想不出from modulename import *你可以做什麼,你不能用import modulename做什麼。你只需要在modulename.前面加上你的名字,這是件好事,而不是壞事。它使您的代碼自行記錄,這就是爲什麼要避免from modulename import *

您可以讓UI和主流程模塊相互導入。遇到問題的唯一方法是如果您在函數範圍之外引用它們之間的名稱。例如

# mainflow.py 
import ui # interpreter stops reading mainflow and starts reading ui 

class Foo: 
    ... 

theUI = ui.UI() 

# ui.py 
import mainflow # mainflow already being loaded; interpretation of ui continues uninterrupted 

def dosomething(): 
    myfoo = mainflow.Foo() # so far so good, not interpreted until the function is called 

class Bar(mainflow.Foo): # mainflow.Foo not reached yet, error here 
    ... 

class UI: 
    ... 

在另一方面,如果UI偶然得到先進口,然後你在theUI = ui.UI()得到錯誤,當所有mainflow得到了詮釋,但UI只被遠解釋作爲import mainflow。但是,只要你把所有的引用都放在函數中,你就可以相處得很好。例如。

# mainflow.py 
import ui 
... 

theUI = None 

def initialize(): 
    global theUI 
    theUI = ui.UI() 

這些類之間的依賴依然存在問題;我建議你不要做那樣的事情。但是,如果你做了,你可以讓整個事情的工作,這種奇怪的做法:

# mainflow.py 
... 

theUI = None 

def initialize(): 
    global theUI 
    theUI = ui.UI() 

import ui # Waht!? Crazy! Import at the bottom of a file. Now all of mainflow's names are guaranteed to exist and ui can access them. 

現在用ui.py的第一個版本,並mainflow.py的最後一個版本,該計劃將編譯和運行。我不真的推薦以上;更好地組織你的代碼,所以你沒有這種依賴關係。但是,如果你所擁有的只是在模塊中的函數之間來回調用,則不必訴諸於這些技巧。

還有更多面向對象的設計方法可以讓你的UI和你的程序流程不直接相互依賴,但是這樣的重新設計會涉及更多的複製和粘貼到文件和前綴名稱module.我不'除非你有特定的原因,否則你認爲你不想過分重新設計。

+0

雖然我同意你說的大部分內容,但最後一部分的代碼存在錯誤。如果在'initialize()'函數中有全局的''''''語句,那麼不需要'theUI = None'。 – martineau

+0

如果你有任何可以在'initialize'之前運行的代碼,這可能是可取的。然後它可以檢查用戶界面是否已經初始化。 – morningstar

+0

啊,是的,使用全局變量的樂趣...... – martineau

相關問題