[英]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. 我希望能够重写该属性,但能够使用超级父级的setter,而不必重写子类中的setter。
Is that pythonicaly possible? pythonicaly有可能吗?
Use just the .getter
decorator of the original property: 仅使用原始属性的
.getter
装饰器:
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). property
描述符对象只是一个对象,即使它可以具有与其关联的多种方法(getter,setter和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. 现有
property
描述符提供的.getter
, .setter
和.deleter
装饰器函数返回描述符本身的副本,但该特定方法已替换。
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. 因此,在
human
基类中,发生的事情是,首先使用@property
装饰器创建了描述符,然后使用同时具有@name.setter
和@name.setter
语法的setter替换了该描述符。 That works because python decorators replace the original decorated function with the same name, it basically executes name = name.setter(name)
. 这是
name = name.setter(name)
,因为python装饰name = name.setter(name)
相同的名称替换了原始装饰的函数,它基本上执行name = name.setter(name)
。 See How does the @property decorator work? 请参见@property装饰器如何工作? 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. 在您的子类中,您只需使用该技巧就可以创建描述符的新副本,而只需替换getter。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.