简体   繁体   English

在Python中覆盖继承属性的getter和setter

[英]Overriding inherited properties’ getters and setters in Python

I'm currently using the @property decorator to achieve “getters and setters” in a couple of my classes. 我目前正在使用@property装饰器在我的几个课程中实现“getter and setters”。 I wish to be able to inherit these @property methods in a child class. 我希望能够在子类中继承这些@property方法。

I have some Python code (specifically, I'm working in py3k) which looks vaguely like so: 我有一些Python代码(具体来说,我在py3k中工作),看起来有点模糊:

class A:
    @property
    def attr(self):
        try:
            return self._attr
        except AttributeError:
            return ''

class B(A):
    @property
    def attr(self):
        return A.attr   # The bit that doesn't work.

    @attr.setter
    def attr(self, value):
        self._attr = value

if __name__ == '__main__':
    b = B()
    print('Before set:', repr(b.attr))
    b.attr = 'abc'
    print(' After set:', repr(b.attr))

I have marked the part that doesn't work with a comment. 我已经标记了与评论无关的部分。 I want the base class' attr getter to be returned. 我希望返回基类'attr getter。 A.attr returns a property object (which is probably very close to what I need!). A.attr返回一个属性对象(可能非常接近我需要的东西!)。

Edit : 编辑
After receiving the answer below from Ned I thought up what I think is a more elegant solution to this problem. 在从Ned收到以下答案后,我想到了我认为对这个问题更优雅的解决方案。

class A:
    @property
    def attr(self):
        try:
            return self._attr
        except AttributeError:
            return ''

class B(A):        
    @A.attr.setter
    def attr(self, value):
        self._attr = value

if __name__ == '__main__':
    b = B()
    print('Before set:', repr(b.attr))
    b.attr = 'abc'
    print(' After set:', repr(b.attr))

The .setter decorator expects a property object which we can get using @A.attr . .setter装饰器需要一个我们可以使用@A.attr获得的属性对象。 This means we do not have to declare the property again in the child class. 这意味着我们不必在子类中再次声明属性。

(This is the difference between working on a problem at the end of the day vs working on it at the beginning of the day!) (这是在一天结束时处理问题与在一天开始时处理问题之间的区别!)

To override a setter in python 2 I did this: 要覆盖python 2中的setter,我这样做了:

class A(object):
    def __init__(self):
        self._attr = None

    @property
    def attr(self):
        return self._attr

    @attr.setter
    def attr(self, value):
        self._attr = value


class B(A):
    @A.attr.setter
    def attr(self, value):
        # Do some crazy stuff with `value`
        value = value[0:3]
        A.attr.fset(self, value)

To understand where A.attr.fset came from see the documentation on the property class: https://docs.python.org/2/library/functions.html#property 要了解A.attr.fset来源,请参阅property类的文档: httpsA.attr.fset

I think you want: 我想你想要:

class B(A):
    @property
    def attr(self):
        return super(B, self).attr

You mention wanting to return the parent class's getter, but you need to invoke the getter, not return it. 你提到想要返回父类的getter,但你需要调用getter,而不是返回它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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