2

我在Python工作(實際上是按名稱傳遞,我認爲),但只要方法參數的行爲相似,這個想法就是語言不可知的:可以依靠自動傳遞引用來改變對象嗎?

如果我有這樣的函數:

def changefoo(source, destination): 
    destination["foo"] = source 
    return destination 

,並調用它像這樣,

some_dict = {"foo": "bar"} 
some_var = "a" 

new_dict = changefoo(some_var, some_dict) 

new_dict將是some_dict修改後的版本,但some_dict是修改。

假設我的例子中像dict這樣的可變結構幾乎總是同樣小,性能不是問題(在應用程序中,我將抽象對象和更改爲不同服務的SOAP請求,其中SOAP請求將比每個服務的數據重新格式化要長一個數量級),這是好嗎?

這些函數中的destination(有幾個,它不僅僅是一個像我的例子中的效用函數)將總是可變的,但我喜歡顯式的:函數的返回值表示確定性計算的結果在你傳入的參數中。我不喜歡使用out參數,但是在將可變結構傳遞給函數時,Python中並沒有真正解決這個問題。一對夫婦的選擇,我尋思着:

  • 複製將被突變的參數,保留原始

    我得的參數在每一個地方我變異它們的功能進行復制,這看起來很麻煩,就像我只是複製了很多。另外我不認爲我會永遠需要原來,它只是似乎混亂返回引用我已經有了變異的對象。

  • 只是用它作爲一個輸入/輸出參數

    我不喜歡這樣,這不是顯而易見什麼功能是幹什麼的,我認爲這是醜陋的。

  • 創建一個裝飾,它會自動複製參數

    好像矯枉過正

所以我在做什麼好嗎?我覺得我隱藏了一些東西,未來的程序員可能會認爲原始對象是基於我調用函數的方式保留下來的(抓取它的結果而不是依賴於它改變原始的事實)。但我也覺得任何替代品都會變得混亂。有更好的方法嗎?請注意,由於軟件的工作方式,向代表抽象數據的類添加一個mutator樣式的方法並不是一個真正的選擇(我必須添加一種方法將該數據結構轉換爲對應的每個服務的SOAP結構爲我們也發送了這些數據 - 目前翻譯邏輯是在每個服務的單獨包)

+2

你可以在函數中就地改變對象,但是你在這裏做的只是在你的函數中重新分配名稱'destination';它根本不影響'some_dict'。 Python傳遞對象。它不像C++那樣具有相同的傳遞引用語義。 – Eevee 2011-05-28 06:18:44

+0

嗯,奇怪,如果我把整個詞典傳遞給它改變它的函數,但是如果我從它傳遞一個值,它不會。讓我改變這個問題 – 2011-05-28 06:25:06

+0

對;分配給某個鍵會更改字典,但分配給某個名稱會重新使用該名稱而不會觸及原始值。 – Eevee 2011-05-28 06:29:19

回答

1

如果你有很多像這樣的功能,我認爲你最好的選擇是寫一個小類來包裝字典,並在原地修改:

class DictMunger(object): 
    def __init__(self, original_dict): 
     self.original_dict = original_dict 

    def changefoo(source) 
     self.original_dict['foo'] = source 

some_dict = {"foo": "bar"} 
some_var = "a" 

munger = DictMunger(some_dict) 
munger.changefoo(some_var) 
# ... 
new_dict = munger.original_dict 

修改自己的對象通常是預期的並且讀取的很好。

+0

嗯好吧,這可以工作,我沒有考慮到這一點。謝謝! – 2011-05-28 06:42:32

相關問題