简体   繁体   English

不使用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. 我希望能够重写该属性,但能够使用超级父级的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM