Я пишу класс, который в какой-то момент добавляет свойства чтения/записи динамически. Моя первая попытка былаДинамическое добавление свойства не работает должным образом
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
ре ad, вызывается функция get_gpio
. Однако при доступе к свойству записи set_gpio
игнорируется (или, скорее, setter
лямбда в getset
).
Я проверил это:
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