2012-10-23 37 views
0

這是一個後續的my previous question變量確保內存位置並沒有改變

了我正在寫一些限制使用PyContract(未PyContracts)一類的方法。作爲後置條件,我想確保某個對象的內存地址沒有改變,即id(myObj)應該在調用該函數之前和之後相同。我怎樣才能用PyContract做到這一點?

下面是我在做什麼現在:

def foo(param1, param2) 
    """ 
     # some other constraints 
     post[param1, param2]: 
      __old__.param1 is param1 
      __old__.param2 is param2 
    """ 

然而,後置條件失敗。我只能想象這是因爲__old__.param1沒有存儲在與param1相同的內存位置。這很有意義,因爲在執行foo之前,PyContract需要複製param1,以便在foo完成執行後檢查其值與param1的值。

假設上述分析屬實,它只能解釋爲什麼id(__old__.param1)id(param1)不同。然而,它仍然沒有回答我如何確保id(param1)不會作爲foo的副作用而改變。我怎麼能在PyContract中檢查這個?

+2

這並不能解釋PyContract的行爲,但您希望通過該後置條件來實現什麼目標? Python通過引用傳遞函數參數,所以函數將無法改變它們在外面引用的內容。如果函數改變了這些名稱在函數內引用的內容,它也不會改變外部綁定。 –

+0

@JamesHenstridge:touche!我根本沒有考慮過python的行爲。我更專注於實際的合同。如果您發表評論作爲答案,我會接受它 - 它完美地回答了我的問題 – inspectorG4dget

回答

1

我不熟悉您使用的PyContract庫,但是您正在測試的實際契約在Python中沒有多大意義,因爲函數參數是通過引用傳遞的。如果你有一個像下面的代碼:

x = a 
y = b 
foo(x, y) 

然後函數將收到由xy在呼叫範圍內命名對象的引用。在函數調用中,您有兩個單獨的變量,並且引用了這些參數。

因此,對函數內部這些變量的更改不會影響調用範圍中的xy的綁定。

+0

您描述了正確傳遞語義的Python參數,但這不稱爲傳遞引用。按引用傳遞並不意味着傳遞了一個被稱爲引用的東西,它意味着一個特定的事物(和其他幾件事情一樣,被稱爲引用),它允許變量傳遞給變量,因此'f(x )'**可以**改變'x'指的是什麼,如果你使用通過引用。另請參閱:http://effbot.org/zone/call-by-object.htm – delnan

+0

@delnan:您的參數存在,但僅當'x'是可變類型時'f(x)'執行一些就地操作在'x'上。如果'f(x)'簡單地將'x'重新賦值給別的東西(在做別的事情之前,就地或者其他地方),那麼當函數調用之前和之後'' 'f(x)' – inspectorG4dget

+0

@ inspectorG4dget(1)你弄錯了,我認爲Python不會**引用傳遞,而'f'因此*不能*改變'x'引用。 – delnan