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)

请允许我谈谈更大的易变性问题

列表是可变对象,支持可变操作和不可变操作。这意味着,更改列表的操作以及返回新列表的操作。相反,元组只是不可变的

因此,要将列表相乘,可以选择两种方法:

  • a*=b
  • 这是一个可变的操作,将在适当位置更改“a”

  • a=a*b
  • 这是一个不可变的操作。它将计算“a*b”,创建一个具有正确值的新列表,并将“a”分配给该新列表

    这里已经有了解决你问题的办法。但是,我建议你读一读。当您将列表(和其他对象)作为参数传递时,您只传递了一个新的引用或指向同一列表的“指针”。因此,在该列表上运行可变操作也将更改您传递的操作。当您编写以下代码时,结果可能是一个非常微妙的错误:

    >>> 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]