2012-02-02 65 views
1

我正在寻找一个Python类装饰器将转换任何元素获得属性的访问,这样的事情:Python类装饰转换元件访问属性访问

@DictAccess 
class foo(bar): 
    x = 1 
    y = 2 

myfoo = foo() 
print myfoo.x # gives 1 
print myfoo['y'] # gives 2 
myfoo['z'] = 3 
print myfoo.z # gives 3 

等是否存在装饰已地方?如果不是,那么实施它的正确方法是什么?我是否应该将__new__包装在类foo上并将__getitem____setitem__属性添加到实例中?那么如何让这些新课程正确地绑定到新课堂呢?我明白DictMixin可以帮助我支持所有的dict功能,但我仍然必须以某种方式获得类中的基本方法。

回答

4

的装饰需要增加__getitem__方法和__setitem__方法:

def DictAccess(kls): 
    kls.__getitem__ = lambda self, attr: getattr(self, attr) 
    kls.__setitem__ = lambda self, attr, value: setattr(self, attr, value) 
    return kls 

这将正常工作与你的示例代码:

class bar: 
    pass 

@DictAccess 
class foo(bar): 
    x = 1 
    y = 2 

myfoo = foo() 
print myfoo.x # gives 1 
print myfoo['y'] # gives 2 
myfoo['z'] = 3 
print myfoo.z # gives 3 

该测试代码产生预期值:

1 
2 
3 
+0

和'__delitem __()'。另外,你可能想要防止踩踏,比如'__dict__'。 – 2012-02-02 02:35:14

+0

@ IgnacioVazquez-Abrams我同意,有许多方法可以扩展基本配方(可能包括由* MutableMapping *提供的完整字典API,也许试图保护对象的命名空间的某些部分)。就目前而言,上面的代码很简单,足以让OP开始这个冒险:-) – 2012-02-02 02:41:39

+1

谢谢,这看起来不错。跺脚__dict__'不是问题 - 我知道哪些属性将被访问。但是获得DictMixin功能的可能性会很有趣。任何想法如何做到这一点? – StasM 2012-02-02 05:59:04