使用@property
知道@property
是为了既能检查参数,又可以用类似属性这样简单的方式来访问类的变量。
但是发现python2.7中继承的子类中使用会有问题
- 继承的子类实现
@property
class Publisher:
def __init__(self):
pass
class DefaultFormatter(Publisher):
def __init__(self, name):
self.name = name
self._data = 0
def __str__(self):
return "{}: '{}' has data = {}".format(type(self).__name__, self.name, self._data)
@property
def data(self):
return self._data
@data.setter
def data(self, new_value):
print("execute data.setter", new_value)
try:
self._data = int(new_value)
except ValueError as e:
print('Error: {}'.format(e))
def main():
df = DefaultFormatter('test1')
print(df)
df.data = 666
print(df.data)
print(df)
if __name__ == '__main__':
main()
输出结果为:
instance: 'test1' has data = 0
666
instance: 'test1' has data = 0
Process finished with exit code 0
调试后发现, df.data = 666
语句并没有进入函数def data(self, new_value):
。因此并没有更改self._data
的值。反而为该对象添加了新的变量self.data
,因此self.data:666
,而self._data:0
。
- 如果没有继承的话,
class Publisher:
def __init__(self):
pass
class DefaultFormatter(object):
def __init__(self, name):
self.name = name
self._data = 0
def __str__(self):
return "{}: '{}' has data = {}".format(type(self).__name__, self.name, self._data)
@property
def data(self):
return self._data
@data.setter
def data(self, new_value):
print("execute data.setter", new_value)
try:
self._data = int(new_value)
except ValueError as e:
print('Error: {}'.format(e))
输出结果为:
DefaultFormatter: 'test1' has data = 0
('execute data.setter', 666)
666
DefaultFormatter: 'test1' has data = 666
调试后发现,代码正常进入了函数 def data(self, new_value):
。
因此在继承的子类中还是尽量不要用@property
了。
至于原因,可以参考使用slots,继承的时候,没有识别出来,而是给该实例动态绑定了一个属性data
同样的,在python2.7中,当继承的时候,__slots__
也不起作用
网友评论