首页 > 解决方案 > 如何为动态添加的属性定义 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')

我只想要这些用户添加的属性的自定义行为。

标签: python

解决方案


自定义 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))

话虽如此,这有点愚蠢,而且很可能您尝试做的任何事情都是不应该做的事情。动态编程一切都很好,但是如果我要审查执行此操作的代码,我会在批准之前对替代解决方案进行长时间的思考。这对我来说是技术债务。


推荐阅读