Python:将可变(?)对象传递给方法
我试图用一个方法实现一个类,该方法调用另一个方法,该方法的对象是类的一部分,在该类中,最低的方法变异对象。我的实现有点复杂,所以我将发布一些伪代码,以便您可以看到我所说的内容:Python:将可变(?)对象传递给方法,python,object,methods,arguments,mutable,Python,Object,Methods,Arguments,Mutable,我试图用一个方法实现一个类,该方法调用另一个方法,该方法的对象是类的一部分,在该类中,最低的方法变异对象。我的实现有点复杂,所以我将发布一些伪代码,以便您可以看到我所说的内容: class test: def __init__(self,list): self.obj = list def mult(self, x, n): x = x*n def numtimes(self, n): self.mult(self.obj,
class test:
def __init__(self,list):
self.obj = list
def mult(self, x, n):
x = x*n
def numtimes(self, n):
self.mult(self.obj, n)
现在,如果创建这种类型的对象并运行numtimes方法,它将不会更新self.obj:
m = test([1,2,3,4])
m.numtimes(3)
m.obj #returns [1,2,3,4]
而我希望它能给我[1,2,3,4,1,2,3,4,1,2,3,4]
基本上,我需要将self.obj传递给mult方法,并让它变异self.obj,这样当我调用m.obj时,我将得到[1,2,3,4,1,2,3,4,1,2,3,4],而不是[1,2,3,4]
我觉得这只是一个理解python如何将对象作为参数传递给方法的问题(就像它在复制对象,而我需要使用指针),但可能不是。我是python新手,这里真的需要一些帮助
提前谢谢 乘法
x*n
创建一个新实例,并且不会改变现有列表。请看这里:
a = [1]
print (id (a) )
a = a * 2
print (id (a) )
这应该起作用:
class test:
def __init__(self,list):
self.obj = list
def mult(_, x, n):
x *= n
def numtimes(self, n):
self.mult(self.obj, n)
请允许我谈谈更大的易变性问题 列表是可变对象,支持可变操作和不可变操作。这意味着,更改列表的操作以及返回新列表的操作。相反,元组只是不可变的 因此,要将列表相乘,可以选择两种方法:
>>> my_list = [1,2,3]
>>> t = test(my_list)
>>> t.numtimes(2)
>>> my_list
[1,2,3,1,2,3] # Not what you intended, probably!
这是我最后的建议。您可以选择使用可变操作,这很好。但然后根据您的参数创建一个新副本,如下所示:
def __init__(self,l):
self.obj = list(l)
或使用不可变操作,并将其重新分配给self:
def mult(self, x, n):
self.x = x*n
或者两者兼而有之,更加安全也无妨:)Python没有指针;将变量传递给函数时,只需将函数参数绑定到变量绑定到的同一个值。如果这是一个可变值,您可以对其进行变异。您的问题是,
x=whatever
只需重新绑定局部变量x
,它不会发生任何变化。同时,您真的需要在适当的位置对self.obj
进行变化吗?如果mult
只是返回x*n
,并且numtimes
是self.obj=self.mult(self.obj,n)
,那会起作用吗?这并不适用于每个用例(例如,如果self.obj
是一个10000x1000矩阵,您可能不想制作额外的副本;如果其他一些代码引用了self.obj
,并且需要查看更改,那么制作副本将不会有帮助)……但是如果是这样,它通常会更简单。感谢您澄清这一点。回想起来,我认为我应该在“mult”中包含一个数组元素赋值,因为这确实是我试图做的最重要的操作。为了简单起见,我只使用了'x=x*n',但我意识到它有点让人困惑。我真的需要根据“mult”方法中的一些逻辑来更改“self.obj”的元素。答案不错,但它并没有真正解释x=x*n
和x*=n
之间的区别。第一个函数只调用x.\uuuu mult(n)
,这应该是一个非变异函数,并将结果分配给x
,这不会影响引用原始值的任何其他人(如调用方)。第二个调用x.\uu imult\uu(n)
,如果可能的话,它应该是变异的,这意味着它确实会影响引用原始值的其他人。或者只显示a*=2;打印(id(a))
而不是试图解释细节。是否存在变异数组分配操作?那么,假设我可以将self.obj作为一个参数传递给mult,在这里我将它的一部分复制到一个虚拟列表中,并将一个(排序的)版本重新复制回self.obj,这样我以后就可以在该方法之外访问self.obj的排序版本了吗?您是否在寻找对列表的可变“赋值”?因为这是可能的:my_list[:]=[1,2,3,4]此外,您可以使用切片来更改列表的一部分,即更改最后三个元素:my_list[-3:][1,2,3]