版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shenziheng1/article/details/83964480
更多的时候,我们需要拓展父类中property的功能。
class Person:
def __init__(self, name):
self.name = name
# Getter funtion
@property
def name(self):
return self._name
# Setter function
@name.setter
def name(self, value):
if not isinstance(value, str):
raise TypeError('Expected a string')
self._name = value
#Deleter function
@name.deleter
def name(self):
raise AttributeError("Can't delete attribute")
class SubPerson(Person):
@property
def name(self):
print('Getting parent class name')
return super().name
@name.setter
def name(self, value):
print('Setting name to', value)
super(SubPerson, SubPerson).name.__set__(self, value)
@name.deleter
def name(self):
print('Deleting name')
super(SubPerson, SubPerson).name.__delete__(self)
p = SubPerson('ziheng')
# >>> Setting name to ziheng
print(p.name)
# >>> Getting parent class name
# ziheng
p.name = 'chunxu'
# >>> Setting name to chunxu
在子类中扩展一个property可能会引起很多不易察觉的问题。 因为property其实是 getter、setter 和 deleter 方法的集合,而不是单个方法。 因此,当扩展property的时候,需要先确定是否要重新定义所有方法还是只修改其中一个。 在该例子中,所有的property方法都被重新定义。 在每个方法中,使用了 super() 来调用父类的实现。
在 setter 函数中使用 super(SubPerson, SubPerson).name.__set__(self, value) 的语句是没有错的。 为了委托给之前定义的setter方法,需要将控制权传递给之前定义的name属性的 __set__() 方法。 不过,获取这个方法的唯一途径是使用类变量而不是实例变量来访问它。 这也是为什么要使用 super(SubPerson, SubPerson) 的原因。
如果只想重定义其中一个方法,那只使用 @property 本身是不够的。
错误代码实例;
class SubPerson(Person):
@property # Doesn't work
def name(self):
print('Getting name')
return super().name
s = SubPerson('ziheng')
# >>> Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "****.py", line 5, in __init__
# self.name = name
# AttributeError: can't set attribute
正确代码实例:
class SubPerson(Person):
@Person.name.getter
def name(self):
print('Getting name')
return super().name
s = SubPerson('ziheng')
print(s.name)
# >>> Getting name
# 'ziheng'
博文参考《python3-cookbook》