python 实例化以后属性更新问题

小夜勃
  • 221

本人刚刚接触Python, 目前使用python 3.6, 遇到了一点关于类属性的问题, 代码如下:

class A():
    def __init__(self):
        self.x = 0
        self.y = 0
        self.z = [self.x, self.y]

    def add_one(self):
        self.x += 1
        # self.z = [self.x, self.y]

a = A()
a.add_one()
print(a.x) # 1
print(a.z) # [0, 0]

问题如下:
假设在add_one方法里面没有self.z = [self.x, self.y]这段代码, 可以发现虽然x是更新了, 但是z并没有随着x的更新而更新, 除非手动加上这段代码才可以实现更新, 请问这是为什么?

另外请教一下有没有其他可以更加简便的方法进行对属性的更新? 因为目前这种代码更新起来很麻烦, 增加一个更新方法就需要将所有被更新的属性手动更新一次

愿有前辈能指点一下, 若有表述不当, 请见谅!

回复
阅读 2.5k
2 个回答

@property 将函数包装为属性

python3

>>> class A():
    def __init__(self):
        self.x = 0
        self.y = 0
        
    @property # 将函数包装为属性
    def z(self):
        return [self.x, self.y]

    def add_one(self):
        self.x += 1

        
>>> a=A()
>>> a.add_one()
>>> a.x
1
>>> a.z
[1, 0]
>>> 

因为你直接修改了self.x的整个引用。self.x += 1的操作是将self.x指向从原先指向的值改为指向另一个值,而不是将其所指向的值修改为另一个值,而self.z仍然存储着原先self.x指向的旧的值,当然不会跟着更新。要达到你想要的类似的效果,可以试试

a = []
b = []
c = [ a, b ]
print(c)
a.append(1)
b.append(2)
print(c)

与实例化与否无关。

上述代码对ab指向的值本身进行了修改,而非修改整个引用使其指向新的值。也就是说,修改后的ab的指向并没有改变(而self.x += 1修改了self.x的指向),因此c的两个元素仍能通过其引用找到与当前ab一致的值

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏