[英]return multiple values in python without breaking previous code
我有一個函數的版本1,如:
def f(a,b,c):
#Some processing
return some_result
后來,我將其升級到版本2。
def f(a,b,c):
#Some processing
#Some more processing
return some_result, additional_result
后一版本返回一個元組。 因此,使用版本1的所有客戶端代碼都已過時。 我可以按需獲得additional_result
嗎?
這就是你得到additional_result
當你問它,而你繼續只得到some_result
仿佛什么都沒有改變。
我想到的一個技巧:
def f(a,b,c, need_additional = False):
#Some processing
#Some more processing
if not need_addional:
return some_result
else:
return some_result, additional_result
還有什么更好的? 還是更通用的?
我認為更優雅的解決方案是讓您的舊功能成為新功能的傳統包裝器:
def f(a,b,c):
some_result, additional_result = f_new(a,b,c)
return some_result
def f_new(a,b,c):
#Some processing
#Some more processing
return some_result, additional_result
我不得不承認我主要使用你建議的模式,而不是我的:),但是向后兼容的默認參數並不是很好的練習。
添加additional_result
作為some_result
字段
如果需要,將some_result
更改為繼承其數據類應該是什么的類,但使用additional_result
。 (所以遺留代碼可以簡單地忽略你的“額外位”)
甚至更好。
只需創建返回多個值的單獨函數。 親吻;)
這些解決方案都不是完美的。
實際上,雖然看起來確實很難看,但我想我更喜歡已經提到的通過out-parameters傳遞額外結果的方法。 我的編碼方式是這樣的:
老來電者:
result = f(a, b, c)
print result
新來電者:
additionalResult = [0]
result = f(a, b, c, additionalResult)
print result, additionalResult[0]
被調用者:
def f(a, b, c, additionalResult=[None]):
#Some processing
#Some more processing
additionalResult[0] = someValue
return some_result
這也是很好的,經常在C中練習,所以有充分的理由相信這不會是我們可能忽略的陷阱,盡管它可能看起來很難看。
雖然我不是Python專家,但我會按照你提到的方式實現它,在我看來,為了實現向后兼容,我認為這是一個非常直接的改變。
如果您不必在同一文件中同時使用這兩個版本,則可以通過包含該方法的2個版本的模塊來控制它,然后僅在調用模塊中導入所需的版本。 然后,當您最終完成並重構舊代碼時,您所要做的就是在完成后更改import語句。
或者,使用from x import y as z
構造,同時在同一模塊中實現這兩種實現。
您還可以在字典中返回額外值作為引用,其引用作為額外參數傳遞,例如:
def f(a,b,c, additional_result_dict = {}):
#Some processing
#Some more processing
additional_result_dict['additional_result'] = additional_result
return some_result
我終於實現它了:
def f(a,b,c, v2 = False):
#Some processing
#Some more processing
if not v2:
return some_result
else:
v2_dict = {}
v2_dict['additional_result'] = additional_result
v2_dict['...'] = ...
return some_result, v2_dict
好處:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.