不使用setter的Python覆盖getter [英] Python overriding getter without setter
问题描述
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.
这在Python上可行吗?
Is that pythonicaly possible?
推荐答案
使用 just 原始属性的.getter
装饰器:
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.
演示:
>>> 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
property
描述符对象只是一个一个对象,即使它可以具有与其关联的多个方法(getter,setter和deleter).现有property
描述符提供的.getter
,.setter
和.deleter
装饰器函数将返回描述符本身的副本,并替换该特定方法.
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.
因此,在您的human
基类中,发生的事情是,您首先使用@property
装饰器 create 描述符,然后用同时具有getter和setter的描述符替换该描述符. @name.setter
语法.这是可行的,因为python装饰器用相同的名称替换了原始装饰函数,它基本上执行name = name.setter(name)
.有关所有方法的详细信息,请参见 @property装饰器如何工作?有效.
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.
在子类中,您只需使用该技巧就可以创建描述符的新副本,而只需替换getter.
In your subclass you simply use that trick to create a new copy of the descriptor with just the getter replaced.
这篇关于不使用setter的Python覆盖getter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!