python 的返回值为list 的 property 绕过 setter 的问题

xiaoxiao2021-02-28  98

当用property装饰一个属性,并且这个属性返回的是一个list(或者一个类,一个dict,都会有同样的情况),那么如果我们使用list的索引去访问list,setter将不起任何作用。 如下所示:

In [1]: class test(object): ...: a = [10,10,10] ...: @property ...: def ads(self): ...: print 'get' ...: return self.a ...: @ads.setter ...: def ads(self, val): ...: print 'set' ...: self.a = val ...: In [2]: test = test() In [3]: test.ads[1] = 1 get In [4]: test.ads get

可以看到,全程并没有运行setter(输出没有出现过“set”),而property的值却被改变了。

如果想要防止这种情况的发生,应该对property的值加以判断,如果不是基础类型,就使用深拷贝,能够避免这种情况的发生。 例如:

In [1]: def is_container(val): ...: '''判断一个变量是否为基本的类型,如果是,就意味着可以直接不需要拷贝赋值''' ...: return not type(val) in (int, float, long, complex, str) ...: In [2]: import copy ...: class test(object): ...: a = [10,10,10] ...: @property ...: def ads(self): ...: print 'get' ...: if not is_container(self.a): ...: return self.a ...: else: ...: return copy.deepcopy(self.a) ...: @ads.setter ...: def ads(self, val): ...: print 'set' ...: self.a = val ...: In [3]: test = test() In [4]: test.ads[1] = 1 get In [5]: test.ads get Out[5]: [10, 10, 10]
转载请注明原文地址: https://www.6miu.com/read-28796.html

最新回复(0)