问题描述
类人类(对象):def __init__(self, name=''):self.name = 姓名@财产定义名称(自己):返回 [email protected]定义名称(自我,价值):self._name = 值类超人(人类):@财产定义名称(自己):返回超级"+ 名称s = 超人('约翰')打印 s.name# 不起作用 :( "AttributeError: can't set attribute"s.name = '杰克'打印 s.name
我希望能够覆盖该属性,但能够使用超级父类的 setter,而不必覆盖子类中的 setter.
这可能是蟒蛇吗?
只使用原始属性的 .getter
装饰器:
类超人(人类):@human.name.getter定义名称(自己):返回超级"+ self._name
请注意,您必须使用全名才能访问父类上的原始属性描述符.
演示:
>>>类超人(人类):... @human.name.getter...定义名称(自我):...返回超级"+ self._name...>>>s = 超人('约翰')>>>打印 s.name超级约翰>>>s.name = '杰克'>>>打印 s.name超级千斤顶property
描述符对象只是一个 对象,即使它可以有多个与之关联的方法(getter、setter 和 deleter).由现有 property
描述符提供的 .getter
、.setter
和 .deleter
装饰器函数返回描述符本身,替换了一种特定的方法.
因此,在您的 human
基类中,您首先使用 @property
装饰器创建描述符,然后将该描述符替换为一个同时具有 getter 和 setter 的 @name.setter
语法.这是有效的,因为 python 装饰器用相同的名称替换了原来的装饰函数,它基本上执行 name = name.setter(name)
.请参阅@property 装饰器如何工作? 了解有关这一切的详细信息有效.
在您的子类中,您只需使用该技巧来创建描述符的新副本,并仅替换 getter.
class human(object):
def __init__(self, name=''):
self.name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
class superhuman(human):
@property
def name(self):
return 'super ' + name
s = superhuman('john')
print s.name
# Doesn't work :( "AttributeError: can't set attribute"
s.name = 'jack'
print s.name
I want to be able to override the property but be able to use the super parent's setter without having to override the setter in the child class.
Is that pythonicaly possible?
Use just the .getter
decorator of the original property:
class superhuman(human):
@human.name.getter
def name(self):
return 'super ' + self._name
Note that you have to use the full name to reach the original property descriptor on the parent class.
Demonstration:
>>> class superhuman(human):
... @human.name.getter
... def name(self):
... return 'super ' + self._name
...
>>> s = superhuman('john')
>>> print s.name
super john
>>> s.name = 'jack'
>>> print s.name
super jack
The property
descriptor object is just one object, even though it can have multiple methods associated with it (the getter, setter and deleter). The .getter
, .setter
and .deleter
decorator functions provided by an existing property
descriptor return a copy of the descriptor itself, with that one specific method replaced.
So in your human
base class what happens is that you first create the descriptor with the @property
decorator, then replace that descriptor with one that has both a getter and a setter with the @name.setter
syntax. That works because python decorators replace the original decorated function with the same name, it basically executes name = name.setter(name)
. See How does the @property decorator work? for the details on how that all works.
In your subclass you simply use that trick to create a new copy of the descriptor with just the getter replaced.
这篇关于Python覆盖没有setter的getter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!