我在写一个类,它在某些时候动态地添加了读/写属性。我第一次尝试是动态添加属性不能按预期工作
class MyGPIO:
def configure(self):
gpio_list = [ "a", "b", "c" ] # only an example here
input_list = [ "b" ]
...
for gpio in gpio_list:
getter = lambda obj: obj.get_gpio(gpio)
setter = lambda obj,val: obj.set_gpio(gpio, val)
if gpio in input_list:
setter = None
setattr(self.__class__, gpio, property(getter, setter))
def get_gpio(self, name):
print "getting %s" % name
return True
def set_gpio(self, name, val):
print "setting %s=%s" % (name, val)
但后来我遇到了在这里https://eev.ee/blog/2011/04/24/gotcha-python-scoping-closures/描述的范围问题,所以我修改了代码,以
def configure(self):
...
for gpio in gpio_list:
def getset(gpio):
getter = lambda obj: obj.get_gpio(gpio)
setter = lambda obj,val: obj.set_gpio(gpio, val)
if gpio in input_list:
setter = None
setattr(self.__class__, gpio, property(getter, setter))
getset(gpio)
这似乎是工作,因为你可以从这个ipython
见会话(magnet
处于gpio_list
)
In [1]: gpio = MyGPIO()
In [2]: gpio.configure(...)
In [3]: gpio.magnet
getting magnet
Out[3]: True
In [4]: gpio.magnet = False
In [5]: gpio.magnet
Out[5]: False
在第一次访问magnet
重新广告属性,get_gpio
函数被调用。但是,当访问写入属性时,将忽略set_gpio
(或中的setter
lambda)。
我选中此:
In [6]: def setme(obj,x):
...: print "obj=%s,x=%s" % (obj,x)
...:
In [7]: class A(object):
...: pass
...:
In [8]: A.a = property(None, lambda obj,x: setme(obj,x))
In [9]: a = A()
In [10]: a.a = "test"
obj=<__main__.A object at 0x7ff544028790>,x=test
在这里它作为我的本意。那么为什么它不适用于我上面的示例?
你是否从继承对象(直接或间接)?属性在Python2旧式类中可能会有奇怪的行为。当你使用属性时,你的类应该从对象继承。 https://wiki.python.org/moin/NewClassVsClassicClass – Tryph
我的类继承自'traits.api.HasTraits' – Pablo