我在寫一個類,它在某些時候動態地添加了讀/寫屬性。我第一次嘗試是動態添加屬性不能按預期工作
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