Files
Python_CookBook_repo/8.类与对象/8.在子类中扩展属性.py

90 lines
2.5 KiB
Python
Raw Permalink Normal View History

2025-09-10 16:12:45 +08:00
# 我们有时候想在子类中定义一些父类没有的属性进行属性拓展
class Person:
def __init__(self, name):
self.name = name
@property
def name(self):
return self._name
@name.setter
def name(self, name):
if not isinstance(name, str):
raise TypeError('name must be str')
else:
self._name = name
@name.deleter
def name(self):
raise AttributeError('name cannot be deleted')
# 我们从Person中继承,并对name属性的功能进行拓展
class SubPerson(Person):
@property
def name(self):
print("Getting name...")
return super().name
@name.setter
def name(self, value):
print("Setting name to {}...".format(value))
super(SubPerson, SubPerson).name.__set__(self, value)
@name.deleter
def name(self):
print("Deleting name...")
super(SubPerson, SubPerson).name.__delete__(self)
# s = SubPerson("Guido")
# s.name
# s.name = "Larry"
# s.name = 42
# 如果只是想拓展属性的其中一个方法,可以使用如下代码实现
# 只修改setter
class SubPerson2(Person):
# 指定父类中属性的某种方法
@Person.name.setter
def name(self, value):
print("Setting name to {}...".format(value))
super(SubPerson2, SubPerson2).name.__set__(self, value)
s2 = SubPerson2("Guido2")
s2.name = "Larry"
#只修改getter
class SubPerson3(Person):
# 我们也可以这样操作
@Person.name.getter
def name(self):
print('Getting name .....')
return super().name
s3 = SubPerson3("Guido3")
s3.name
s3.name = "Larry"
s3.name
# Python3让我们太舒服了,super的本质是super(类名, self),这些参数被省略了,它的意思其实是从self的MRO列表里寻找类名的下一个位置
# 所以这里的 super(SubPerson, SubPerson).name 其实是在SubPerson的MRO列表中寻找SubPerson的下一个类,用途是找到Person
# 万万记住,这种方式一次只能修改一个方法,如果一次修改多个,生效的只有最后被定义的那个
#比如这里生效的只有setter
class SubPerson4(Person):
# 我们也可以这样操作
@Person.name.getter
def name(self):
print('Getting name .....')
return super(SubPerson4, SubPerson4).name.__get__(self)
@Person.name.setter
def name(self, value):
print("Setting name to {}...".format(value))
super(SubPerson4, SubPerson4).name.__set__(self, value)
s4 = SubPerson4("Guido4")
s4.name
s4.name = "Larry"
s4.name