Python覆盖没有setter的getter [英] Python overriding getter without setter

查看:36
本文介绍了Python覆盖没有setter的getter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类人类(对象):def __init__(self, name=''):self.name = 姓名@财产定义名称(自己):返回 self._name@name.setter定义名称(自我,价值):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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆