我如何编写类方法,使其参数不被改变?

时间:2014-11-16 13:11:18

标签: python class methods

在一个python类中,我有一些方法:

def method0(self,x,y,z):
 s=x
 s=method1(self,s,y)
 s=method2(self,s,z)
 return s

当我运行上面的代码(我不希望x被更改)时, x 会随着 s 而改变。(为什么?)
但是,当我使用复制模块x时,不会改变:

def method0(self,x,y,z):
 s=copy.copy(x)
 s=method1(self,s,y)
 s=method2(self,s,z)
 return s

如何编写 method0 以便x不被更改?

2 个答案:

答案 0 :(得分:2)

完全按照您的方式 - 通过在修改值之前复制值。 Python没有const等概念,比如C ++(无论如何都不太好),所以没有办法强制你只对你的参数使用非变异操作。

并且也没有办法声明一个参数作为副本传递,而不是作为参考传递。

如果您知道自己的域名(例如在您的情况下是矩阵),您可以尝试&通过在装饰器中复制参数,使这种方法更具说明性。

 from copy import deepcopy
 from functools import wraps

 def deepcopied(f):
     @wraps(f)
     def _d(*args, **kwargs):
         real_args = []
         real_kwargs = {}
         for arg in args:
             if isinstance(arg, (list, dict)):
                 arg = deepcopy(arg)
             real_args.append(arg)
         for key, value in kwargs.iteritems():
             if isinstance(value, (list, dict)):
                 value = deepcopy(value)
             real_kwargs[key] = value
         return f(*real_args, **real_kwargs)
     return _d


 @deepcopied
 def foo(a, b=None):
     a.append("mutated!")
     if b is not None:
         b["bar"].append("mutated")


 one = list()
 two = dict(bar=list())

 foo(one, two)
 print one, two

答案 1 :(得分:1)

防止x被改变的另一种方法是确保你的所有函数都不会改变它们的参数。您的问题源于method1或method2正在改变其参数的事实。但是你也从这些方法返回值。修复这些方法不要改变传递给它们的矩阵,只修改新的矩阵,你就可以解决问题了。