python - 动态向类添加属性

标签 python properties

这个问题之前曾在 Stack Overflow 上被问过,但似乎没有一个答案能够准确解决我需要做的事情。就我而言,我希望这些动态添加的属性成为从数据库存储和读取值的快捷方式,因此不幸的是它并不那么容易 as in this answer (其中使用了 lambda 函数)或 this one (其中值存储在字典中):我必须调用该类的其他方法。

这是我的尝试:

import operator

class Foo(object):

    def get_value(self, name):
        # read and return value from database
        return -1

    def set_value(self, name, value):
        # store value in database
        pass

def add_metadata_property(name):
    getter = operator.methodcaller('get_value', name)
    setter = operator.methodcaller('set_value', name) # gets value at runtime
    setattr(Foo, name, property(getter, setter))

add_metadata_property('spam')
f = Foo()
f.spam # works!
f.spam = 2

然而,最后一行引发:

Traceback (most recent call last):
File "<stdin>", line 27, in <module>
TypeError: methodcaller expected 1 arguments, got 2

关于如何实现这一目标有什么想法吗?

最佳答案

我不知道你为什么在这里使用operator.methodcaller。 当您调用f.spam=2时,它将调用setter。 setter = operator.methodcaller('set_value', name) 表示 setter(r) = r.set_value(name)。在你的情况下没有任何意义。

我建议你这样写,使用@classmethod:

class Foo(object):

    @classmethod
    def get_value(self, name):
        # read and return value from database
        return -1
    @classmethod
    def set_value(self,  name, value):
        # store value in database
        pass

def add_metadata_property(name):
    setattr(Foo, name, property(Foo.get_value, Foo.set_value))

add_metadata_property('spam')
f = Foo()
f.spam # works!
f.spam = 2

如果这对您有帮助,请确认为答案。谢谢!

关于python - 动态向类添加属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24509737/

相关文章:

java - 如何将 .properties 文件更改为 XML 文件?

objective-c - 在现代 Objective-C 中覆盖 setter 和 getter 时访问生成的 ivar 时出错

python - PyCharm 为新创建的文件设置模式

python - 如何返回多列和限制行

python - 将列表转换为 1 列 Pandas 数据框

python - Marshmallow @validates 不会引发错误

Javascript:用于揭示模块模式的通用 getter/setter

objective-c - 通过 "self."访问属性是否比直接访问 ivar 慢?

Python牛奶库: object weights issue

php - 从子方法访问时,父方法设置的父类属性为空