Access superclass' property setter in subclass

泄露秘密 提交于 2019-12-10 10:45:03

问题


I have a SuperClass which defines a property and it's setter, like so:

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

    @property
    def mode(self):
        # to be overriden in subclass to implement the actual getter code
        raise NotImplementedError

    @mode.setter
    def mode(self, value):
        # common assertions and input validations
        self._set_mode(value)

    def _set_mode(self, value):
        # to be overriden in subclass to implement the actual setter code
        raise NotImplementedError


class B(A):
    @property
    def mode(self):
        return self._mode

    def _set_mode(self, value):
        self._mode = value


obj = B()
obj.mode = 'test'

Which raises

obj.mode = 'test'
AttributeError: can't set attribute

It would seem that I have to register a setter in B. I'd usually do this like @A.mode.setter, but that doesn't quite apply here as I don't actually want to define a new setter in B, just re-use the one from A.
Does anyone have a hint on how to solve this? Might be trivial, but I'm not seeing it right now :/


回答1:


the getter and setter are stored as attributes of the property object (respectively as .fget and .fset), so as soon as you overload the property in a child class you most explicitely provide both getter and setters, ie:

class B(A):
    @property
    def mode(self):
        return self._mode

    @mode.setter
    def mode(self, value):
        self._mode = value

So if you want to make the getter and/or setter overloadable without having to redeclare the property, you have to define a _get_mode method and make your property's getter delegate to this method, just like you did for the setter.

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

    @property
    def mode(self):
        return self._get_mode()

    def _get_mode(self):
        # to be overriden in subclass to implement the actual getter code
        raise NotImplementedError

    @mode.setter
    def mode(self, value):
        # common assertions and input validations
        self._set_mode(value)

    def _set_mode(self, value):
        # to be overriden in subclass to implement the actual setter code
        raise NotImplementedError


class B(A):

    def _get_mode(self):
        return self._mode

    def _set_mode(self, value):
        self._mode = value


来源:https://stackoverflow.com/questions/42763283/access-superclass-property-setter-in-subclass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!