2011-12-06 54 views
13

由於Python的範圍規則,在範圍內初始化之後的所有變量都可用。由於條件不會引入新的範圍,因此不一定需要其他語言的構造(例如在該條件之前初始化變量)。例如,我們可能有:條件變量初始化的pythonic方式是什麼?

def foo(optionalvar = None): 
    # some processing, resulting in... 
    message = get_message() 
    if optionalvar is not None: 
     # some other processing, resulting in... 
     message = get_other_message() 
    # ... rest of function that uses message 

或者,我們可以有替代:

def foo(optionalvar = None): 
    if optionalvar is None: 
     # processing, resulting in... 
     message = get_message() 
    else: 
     # other processing, resulting in... 
     message = get_other_message() 
    # ... rest of function that uses message 

當然,get_messageget_other_message功能可能是多行代碼,並基本上不相關的(你可以假設每個路徑之後的程序狀態是相同的);這裏的目標是使message可以在該部分的功能之外使用。

我見過的其他問題,多次使用後一種結構,如:

其中結構會更容易接受?

+1

這不完全取決於您是否希望'get_message'有條件地或無條件地運行嗎? – delnan

+0

這裏的想法不是調用的函數,而是'message'的構造:函數本身是不相關的。 –

+1

無論是否爲函數,其中一種語義差異是無條件地運行一半的代碼。如果它有所作爲,那麼辯論風格就沒什麼意義了。 – delnan

回答

12

Python中也有一個非常有用的,如果語法模式,您可以使用此

message = get_other_message() if optional_var else get_message() 

或者,如果你想與無

message = get_other_message() if optional_var is not None else get_message() 

嚴格比較不像例如1)您發佈這並未不必要地調用get_message()。

+1

這是** Pythonic做條件分配(自v2.5以來)的方式,至少就語言本身而言。查看[PEP 308](http://docs.python.org/release/2.5/whatsnew/pep-308.html)瞭解更多信息。 – voithos

+0

它也看起來像PEP 308建議第二種格式是以前可以接受的方式。很高興知道! –

1

我認爲沒有對此設置明確的規則更爲pythonic,而只是堅持小函數更好的理念(部分原因是因爲只有在引入新名稱時才能保留在您的腦海中)。

我想盡管如果你的條件測試比if/else複雜得多,你可能會冒着失敗的風險,你以後會使用一個未定義的名字,導致可能的運行時錯誤,除非你非常小心。在可能的情況下,這可能是第一種風格的論據。

0

答案取決於是否有需要的get_message()的副作用。

在大多數情況下,顯然第二個獲勝,因爲產生不需要的結果的代碼不會執行。但是如果你需要副作用,你應該選擇第一個版本。

0

在條件之外初始化變量可能會更好(讀取:更安全)。如果您必須定義其他條件或刪除一些條件,稍後message的用戶可能會收到未初始化的變量異常。

4

一般來說,第二種方法更好,更通用,因爲它不涉及無條件地致電get_message。這可能是確定的,如果該函數不是資源的激勵,但考慮搜索功能

def search(engine): 
    results = get_from_google() 
    if engine == 'bing': 
     results = get_from_bing() 

顯然,這是不好的,我不認爲這樣的壞情況下的對第二種情況,所以基本上是一個的做法,會突破所有選項,最後默認是最好的例如

def search(engine): 
    if engine == 'bing': 
     results = get_from_bing() 
    else: 
     results = get_from_google()