如何动态地向类添加属性?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (13)

目标是创建一个模拟类,它的行为类似于db结果集。

例如,如果数据库查询使用dict表达式返回,{'ab':100, 'cd':200},然后我想看到:

>>> dummy.ab
100

一开始我想也许我可以这样做:

ks = ['ab', 'cd']
vs = [12, 34]
class C(dict):
    def __init__(self, ks, vs):
        for i, k in enumerate(ks):
            self[k] = vs[i]
            setattr(self, k, property(lambda x: vs[i], self.fn_readyonly))

    def fn_readonly(self, v)
        raise "It is ready only"

if __name__ == "__main__":
    c = C(ks, vs)
    print c.ab

c.ab返回属性对象。

替换setattr与...一致k = property(lambda x: vs[i])根本没用。在运行时创建实例属性的正确方法是什么?

提问于
用户回答回答于

我想我应该扩展这个答案.

>>> class Foo(object):
...     pass
... 
>>> foo = Foo()
>>> foo.a = 3
>>> Foo.b = property(lambda self: self.a + 1)
>>> foo.b
4

描述符实际上是Python公开其整个OO实现的管道的方式。事实上,还有另一种类型的描述符比property...

>>> class Foo(object):
...     def bar(self):
...         pass
... 
>>> Foo().bar
<bound method Foo.bar of <__main__.Foo object at 0x7f2a439d5dd0>>
>>> Foo().bar.__get__
<method-wrapper '__get__' of instancemethod object at 0x7f2a43a8a5a0>

__get__将调用实例作为第一个参数进行调整;

def __get__(self, instance, owner):
    return functools.partial(self.function, instance)
用户回答回答于

你可以在字典里拼写“b”作为A.B?这很简单:

class atdict(dict):
    __getattr__= dict.__getitem__
    __setattr__= dict.__setitem__
    __delattr__= dict.__delitem__

扫码关注云+社区