Python 如何编写类方法,使其';谁的论点不能改变?
在python类中,我有一些方法:Python 如何编写类方法,使其';谁的论点不能改变?,python,class,methods,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 如何
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
如何编写方法0,使x不被更改?与您所做的完全相同-在修改值之前复制值。Python没有C++之类的稳定性概念(无论如何都不是太大),所以没有办法强制你只在参数上使用非突变操作。 而且,也没有办法将参数声明为作为副本传递,而不是作为引用传递 如果您知道您的域(例如,在您的例子中是矩阵),您可以尝试&通过在decorator中复制参数使这种方法更具声明性
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
完全按照您的方式—在修改值之前复制值。Python没有C++之类的稳定性概念(无论如何都不是太大),所以没有办法强制你只在参数上使用非突变操作。 而且,也没有办法将参数声明为作为副本传递,而不是作为引用传递 如果您知道您的域(例如,在您的例子中是矩阵),您可以尝试&通过在decorator中复制参数使这种方法更具声明性
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
完全按照您的方式—在修改值之前复制值。Python没有C++之类的稳定性概念(无论如何都不是太大),所以没有办法强制你只在参数上使用非突变操作。 而且,也没有办法将参数声明为作为副本传递,而不是作为引用传递 如果您知道您的域(例如,在您的例子中是矩阵),您可以尝试&通过在decorator中复制参数使这种方法更具声明性
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
完全按照您的方式—在修改值之前复制值。Python没有C++之类的稳定性概念(无论如何都不是太大),所以没有办法强制你只在参数上使用非突变操作。 而且,也没有办法将参数声明为作为副本传递,而不是作为引用传递 如果您知道您的域(例如,在您的例子中是矩阵),您可以尝试&通过在decorator中复制参数使这种方法更具声明性
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
防止x被更改的另一种方法是确保任何函数都不会更改其参数。您的问题源于method1或method2正在更改其参数这一事实。但是您也从这些方法返回值。修复这些方法,使其不更改传递给它们的矩阵,而只更改新矩阵,那么问题就解决了。防止x更改的另一种方法是确保所有函数都不会更改其参数。您的问题源于method1或method2正在更改其参数这一事实。但是您也从这些方法返回值。修复这些方法,使其不更改传递给它们的矩阵,而只更改新矩阵,那么问题就解决了。防止x更改的另一种方法是确保所有函数都不会更改其参数。您的问题源于method1或method2正在更改其参数这一事实。但是您也从这些方法返回值。修复这些方法,使其不更改传递给它们的矩阵,而只更改新矩阵,那么问题就解决了。防止x更改的另一种方法是确保所有函数都不会更改其参数。您的问题源于method1或method2正在更改其参数这一事实。但是您也从这些方法返回值。修复这些方法,使其不更改传递给它们的矩阵,而只生成新矩阵,您就解决了问题。您已经这样做了。我不想使用copy!不是另一种方法吗?使用构造函数如何?@REACHUS我不知道它…你能为我的案例编写它吗?@REACHUS构造函数需要更改什么?你已经这么做了。我不想使用copy!不是另一种方法吗?使用构造函数如何?@REACHUS我不知道它…你能为我的案例编写它吗?@REACHUS构造函数需要更改什么?你已经这么做了。我不想使用copy!不是另一种方法吗?使用构造函数如何?@REACHUS我不知道它…你能为我的案例编写它吗?@REACHUS构造函数需要更改什么?你已经这么做了。我不想使用copy!不是另一种方法吗?使用构造函数如何?@REACHUS我不知道它…你能为我的案例编写它吗?@REACHUS构造函数需要更改什么?