2017-10-21 99 views
-3

假設我們有一個函數:在python中,如何使輸入參數的函數不可變?

import copy 

def demo_function(list_in) 
    list_out = copy.deepcopy(list_in) 
    list_in.append("howdy") 
    return list_out 

請注意,我們追加到list_in而不是list_out。但demo_function實際上不應修改其輸入。我們想要執行這個。如果有人不小心修改list_indemo_function正文內部的某處,應該拋出錯誤我們如何實現這種類型的錯誤檢查?

以下是我的最佳嘗試,但它不起作用。字符串「你好」仍然最終被追加到list_in;不會引發錯誤

class Frozen(object): 
    # The Frozen class was developed by ActiveState Software Inc. 
    def __init__(self, value): 
     self._value = value 

    def __getattribute__(self, name): 
     if name == '_value': return super(Frozen, self).__getattribute__(name) 
     v = getattr(self._value, name) 
     return v if hasattr(v, '__hash__') else Frozen(v) 

    def __setattr__(self, name, value): 
     if name == '_value': super(Frozen, self).__setattr__(name, value) 
     else: raise Exception("Can't modify frozen object {0}".format(self._value)) 

def const(some_function):  
    def wrapper(fargs,*args,**kwargs): 
     for f in fargs: 
      f = Frozen(f) 
      pass 
     for a in args: 
      a = Frozen(a) 
      pass 
     for k in kwargs: 
      k = Frozen(k) 
      pass 
     some_function(fargs, *args, **kwargs)  
    return wrapper 

@const 
def demo_function(list_in): 
    list_out = copy.deepcopy(list_in) 
    list_in.append("howdy") 
    return list_out 

lisandra = [1, 2, 3, 4, 5] 

modified_lisandra = demo_function(lisandra) 

print(lisandra) 

編輯:

我很後悔,用列表作爲我的榜樣。我真的想要一個通用的解決方案,無論它們的數據類型是什麼,都可以使函數的輸入不可變(const)。將python列表轉換爲元組非常簡單。但是,如果函數的輸入是某個用戶定義的類的實例呢?你不知道如何將它轉換成元組。即使您確實知道如何將對象轉換爲元組,您也不想爲項目中的每個數據類型編寫不同的解決方案。我們希望單個解決方案能夠凍結函數輸入的值,而不管這些輸入的數據類型如何。

+0

使用一個元組? 'lisandra =(1,2,3,4,5)' – James

+0

您可能想改爲使用元組。 –

+0

爲什麼你想要它是不可變的?你希望獲得什麼? –

回答

0

你總是可以嘗試這樣的事情..

import copy 

def demo_function(list_in): 
    original = list_in[:] 
    list_out = copy.deepcopy(list_in) 
    list_in.append("howdy") 
    assert original == list_in 
    return list_out 
相關問題