在一个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不被更改?
答案 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正在改变其参数的事实。但是你也从这些方法返回值。修复这些方法不要改变传递给它们的矩阵,只修改新的矩阵,你就可以解决问题了。