python - 如何为动态添加的属性定义 setter、getter
问题描述
我有一堂课如下:
class A:
def __init__(self):
pass
def add_attr(self, name):
setattr(self, name, 'something')
如何定义自定义设置器、获取器self.name
?我不能使用__setattr__
,__getattribute__
因为这也会改变的行为add_attr
。
编辑:这个类的用户将添加任意数量的任意名称的属性:
a = A()
a.add_attr('attr1')
a.add_attr('attr2')
我只想要这些用户添加的属性的自定义行为。
解决方案
自定义 getter 和 setter 逻辑?这就是 aproperty
的用途。通常这些用于神奇地屏蔽函数调用并使它们看起来像属性访问
class MyDoubler(object):
def __init__(self, x):
self._x = x
@property
def x(self):
return x * 2
@x.setter
def x(self, value):
self._x = value
>>> md = MyDoubler(10)
>>> md.x
20
>>> md.x = 20
>>> md.x
40
>>> md._x
20
但是没有规则说你不能滥用这种权力来为你的 getter 和 setter 添加自定义行为。
class A(object):
def __init__(self):
pass
@staticmethod
def default_getter_factory(name):
def default_getter(self):
return self.name
return default_getter
@staticmethod
def default_setter_factory(name):
def default_setter(self, value):
setattr(self, name, value)
return default_setter
def add_attr(self, name, getterfactory=None, setterfactory=None):
private_name = f"_{name}"
if getterfactory is None:
getterfactory = self.__class__.default_getter_factory
if setterfactory is None:
setterfactory = self.__class__.default_setter_factory
getter, setter = getterfactory(private_name), setterfactory(private_name)
getter = property(getter)
setattr(self.__class__, name, getter)
setattr(self.__class__, name, getter.setter(setter))
话虽如此,这有点愚蠢,而且很可能您尝试做的任何事情都是不应该做的事情。动态编程一切都很好,但是如果我要审查执行此操作的代码,我会在批准之前对替代解决方案进行长时间的思考。这对我来说是技术债务。
推荐阅读
- android - 谷歌播放控制台说“你不能编辑这个应用程序,直到你创建一个声明敏感权限的新应用程序版本”如何解决?
- ruby-on-rails - 1 个错误禁止保存这篇文章:
- spring - 使用 OpenAPI Maven 插件生成 API 文档
- jquery - Arctext 插件代码仅在单击时工作一次
- ios - 两个函数在 Swift 中调用
- regex - Notepad++ 中的日期范围正则表达式
- r - 使用hadoop命令提取时间戳时如何分开小时和日期
- html - 带有可折叠固定侧边栏的 Bootstrap 固定导航栏
- reactjs - 同时反应两个上下文
- java - 异无线电不可见,詹金斯插件