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
我希望能够覆盖该属性,但能够使用超级父级的setter,而不必覆盖子类中的setter。
pythonicaly有可能吗?
仅 使用.getter原始属性的装饰器:
.getter
class superhuman(human): @human.name.getter def name(self): return 'super ' + self._name
请注意,您必须使用全名才能到达父类上的原始属性描述符。
示范:
>>> 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描述对象就是 一个 对象,尽管它可以有多个与之相关的方法(吸气,setter和删除器)。现有描述符提供的.getter,.setter和.deleter装饰器函数将property返回描述符本身的副本,并替换该特定方法。
property
.setter
.deleter
因此,在human基类中发生的情况是,首先使用装饰器 创建 了描述符@property,然后用@name.setter语法同时具有getter和setter的描述符替换了该描述符。之所以可行,是因为python装饰器用相同的名称替换了原始装饰函数,它基本上会执行name = name.setter(name)。请参见@property装饰器如何工作?有关所有工作原理的详细信息。
human
@property
@name.setter
name = name.setter(name)
在您的子类中,您只需使用该技巧即可创建描述符的新副本,而只需替换getter。