简体   繁体   中英

Defining @property.setter in Abstract Base Class gives AttributeError

An Abstract Base Class Base has a @abstractmethod named data which is also a @property .

Question: Is there a way to define the property setter data.setter in the Base class, so that we don't have to repeatedly define the setter method in all the subclasses (ie Foo )?

Code showing AttributeError when defining data.setter in ABC

from abc import ABC, abstractmethod

def reload_data():
    return ['hello']


class Base(ABC):
    @property
    @abstractmethod
    def data(self):
        pass

    @data.setter               # <----- AttributeError if this is defined here
    def data(self, value):
        self._data = value


class Foo(Base):
    def __init__(self):
        self._data = None

    @property
    def data(self):
        if self._data is None:
            self._data = reload_data()
        return self._data

    # @data.setter              # <----- Defining it here avoids AttributeError, but 
    # def data(self, value):             causes code repetition in all the subclasses of Base
    #     self._data = value

foo = Foo()
foo.data = ['world']
print(foo.data)

I don't know if there's a way to do it with @property decorators, but doing it "manually" as shown below seems to work.

from abc import ABC, abstractmethod


def reload_data():
    return ['hello']


class Base(ABC):
    @abstractmethod
    def _get_data(self):
        pass

    # Non-abstract.
    def _set_data(self, value):
        self._data = value


class Foo(Base):
    def __init__(self):
        self._data = None

    # Define inherited abstract method.
    def _get_data(self):
        if self._data is None:
            self._data = reload_data()
        return self._data

    data = property(_get_data, Base._set_data)


foo = Foo()
foo.data = ['world']
print(foo.data)  # ['world']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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