python对象属性修改

python对象属性修改,python,numpy,class,object,attributes,Python,Numpy,Class,Object,Attributes,这对我来说真的很令人惊讶(而且花费在调试上的时间也很昂贵): 我的问题是: 这是因为numpy数组(深度拷贝)的属性吗 有没有办法“修复”对象属性,除非我显式地修改它们 这是一个奇怪的参考与价值问题 因为self是一个引用,所以测试变量是对self.init_值的引用 因此,您正在修改该属性@matfux的解决方案让您的变量存储self.init_值的副本,而不是对它的引用 老实说,在大多数OOP情况下,这是一个棘手的问题。这是一个奇怪的参考与价值问题 因为self是一个引用,所以测试变量是对s

这对我来说真的很令人惊讶(而且花费在调试上的时间也很昂贵):

我的问题是:

  • 这是因为numpy数组(深度拷贝)的属性吗
  • 有没有办法“修复”对象属性,除非我显式地修改它们

  • 这是一个奇怪的参考与价值问题

    因为self是一个引用,所以测试变量是对self.init_值的引用

    因此,您正在修改该属性@matfux的解决方案让您的变量存储self.init_值的副本,而不是对它的引用


    老实说,在大多数OOP情况下,这是一个棘手的问题。

    这是一个奇怪的参考与价值问题

    因为self是一个引用,所以测试变量是对self.init_值的引用

    因此,您正在修改该属性@matfux的解决方案让您的变量存储self.init_值的副本,而不是对它的引用

    老实说,在大多数OOP情况下,这是一个棘手的问题。

    对于您的问题1): 让我们先看看这里发生了什么

    self.init_value = np.array([1,2])
    
    在内存中创建具有所提供值的np.array对象,并将标签self.init_值分配给该对象

    现在,在这一步

    test = self.init_value
    
    将另一个标签test分配给self.init_值所指向的内存位置。您可以通过修改func()来测试这一点,如下所示:

    def func():
        test = self.init_value
    
        # Both these values will be same.
        print(hex(id(test)))
        print(hex(id(self.init_value)))
    
        test[-1] = 0
        return test
    
    import copy
    
    test = copy.deepcopy(self.init_value)
    
    因此,当您执行test[-1]=0时,您基本上是在访问test指向的对象的最后一个元素,并将其更改为值0,因为self.init_valuetest都指向同一个对象,它会被修改

    但是,如果重新指定具有相同标签名称的其他对象,则该标签将从以前的对象中删除并附着到此新对象。您可以通过使用以下代码检查内存位置来验证这一点:

    hex(id(your_label))
    
    关于你的问题2:

    如果您不希望测试修改self.init_值,请修改代码以使用deepcopy(),如下所示:

    def func():
        test = self.init_value
    
        # Both these values will be same.
        print(hex(id(test)))
        print(hex(id(self.init_value)))
    
        test[-1] = 0
        return test
    
    import copy
    
    test = copy.deepcopy(self.init_value)
    
    对你的问题1): 让我们先看看这里发生了什么

    self.init_value = np.array([1,2])
    
    在内存中创建具有所提供值的np.array对象,并将标签self.init_值分配给该对象

    现在,在这一步

    test = self.init_value
    
    将另一个标签test分配给self.init_值所指向的内存位置。您可以通过修改func()来测试这一点,如下所示:

    def func():
        test = self.init_value
    
        # Both these values will be same.
        print(hex(id(test)))
        print(hex(id(self.init_value)))
    
        test[-1] = 0
        return test
    
    import copy
    
    test = copy.deepcopy(self.init_value)
    
    因此,当您执行test[-1]=0时,您基本上是在访问test指向的对象的最后一个元素,并将其更改为值0,因为self.init_valuetest都指向同一个对象,它会被修改

    但是,如果重新指定具有相同标签名称的其他对象,则该标签将从以前的对象中删除并附着到此新对象。您可以通过使用以下代码检查内存位置来验证这一点:

    hex(id(your_label))
    
    关于你的问题2:

    如果您不希望测试修改self.init_值,请修改代码以使用deepcopy(),如下所示:

    def func():
        test = self.init_value
    
        # Both these values will be same.
        print(hex(id(test)))
        print(hex(id(self.init_value)))
    
        test[-1] = 0
        return test
    
    import copy
    
    test = copy.deepcopy(self.init_value)
    

    这是因为您正在动态更改
    int\u值。改为使用
    test=self.init\u value.copy()
    。好的,我明白了。但我仍然感到惊讶的是,对象属性是“动态”可修改的,这取决于属性的类型(在本例中为numpy数组)。我认为它们在默认情况下是不可修改的,除非我明确地说self.init_value=new_value。这是因为您正在动态地更改
    int_值。改为使用
    test=self.init\u value.copy()
    。好的,我明白了。但我仍然感到惊讶的是,对象属性是“动态”可修改的,这取决于属性的类型(在本例中为numpy数组)。我认为它们在默认情况下是不可修改的,除非我明确地说self.init_value=new_value。是的,正如你所说,对我来说,棘手的事情是“self是一个引用”。我知道在b=a(a是numpy数组)的情况下会进行动态修改,然后b中的更改将修改a。我只是从来没有想过同样的事情适用于这里(再次,因为我没有意识到“自我是一个参照物”)是的,正如你所说,对我来说,棘手的事情是“自我是一个参照物”。我知道在b=a(a是numpy数组)的情况下会进行动态修改,然后b中的更改将修改a。我只是从来没有想过同样的事情也适用于这里(再次,因为我没有意识到“自我是一个参照物”)