【问题标题】:Python overriding getter without setterPython覆盖没有setter的getter
【发布时间】:2014-11-12 02:06:18
【问题描述】:
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

我希望能够覆盖该属性,但能够使用超级父级的设置器,而不必覆盖子类中的设置器。

这可能吗?

【问题讨论】:

    标签: python oop properties setter getter


    【解决方案1】:

    使用只是原始属性的.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 描述符对象只是 一个 对象,尽管它可以有多个与之关联的方法(getter、setter 和 deleter)。现有 property 描述符提供的 .getter.setter.deleter 装饰器函数返回描述符本身的副本,并替换了该特定方法。

    所以在您的human 基类中,您首先创建 带有@property 装饰器的描述符,然后将该描述符替换为同时具有getter 和setter 的描述符@name.setter 语法。之所以有效,是因为 python 装饰器用相同的名称替换了原来的装饰函数,它基本上执行name = name.setter(name)。有关所有工作原理的详细信息,请参阅How does the @property decorator work?

    在您的子类中,您只需使用该技巧创建描述符的新副本,只需替换 getter。

    【讨论】:

      猜你喜欢
      • 2011-03-11
      • 2014-06-10
      • 1970-01-01
      • 2018-11-08
      • 1970-01-01
      • 2013-11-11
      • 2015-05-11
      相关资源
      最近更新 更多