python - 在抽象基类中定义 @property.setter 会产生 AttributeError
问题描述
一个抽象基类Base
有一个@abstractmethod
命名data
,它也是一个@property
.
问题:有没有办法data.setter
在Base
类中定义属性setter,这样我们就不用在所有子类(即Foo
)中重复定义setter方法了?
data.setter
在 ABC 中定义时显示 AttributeError 的代码
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)
解决方案
我不知道是否有办法用@property
装饰器来做,但如下所示“手动”做似乎有效。
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']
推荐阅读
- java - 信息:API 'variant.getMergeResources()' 已过时,已替换为 'variant.getMergeResourcesProvider()'
- excel - 获取运行时错误“424”:需要对象
- python - Python 随机使用 if 语句
- kotlin - Dokka:将代码示例包含到包文档中
- javascript - 如何将 DIV 默认设置为 style.display = "none"?
- github - 推送我的 github 文件时遇到问题
- unicode - Unicode 标志在 Firefox 上是可以的,但在 Chromium 中是两个字母;例如
- ubuntu - 用 Sed 用回车替换行
- python - 迭代合并多个海量数据帧而不会耗尽内存
- sql - SQL Server中随机选择8行数据,需要优化