Я хочу создать декоратор, который позволит мне вернуться к декорированному объекту и извлечь из него другой декоратор, так же, как вы можете использовать setter / deleter для свойств:
@property
def x(self):
return self._x
@x.setter
def x(self, y):
self._x = y
В частности, я хотел бы, чтобы он действовал в основном так же, как свойство, но эмулировал последовательность вместо одного значения. Вот мой первый выстрел, но, похоже, он не работает:
def listprop(indices):
def dec(func):
class c(object):
def __init__(self, l):
self.l = l
def __getitem__(self, i):
if not i in self.l:
raise Exception("Invalid item: " + i)
return func(i)
@staticmethod
def setter(func):
def set(self, i, val):
if not i in self.l:
raise Exception("Invalid item: " + i)
func(i, val)
c.__setitem__ = set
return c(indices)
return dec
# ...
class P:
@listprop(range(3))
def prop(self, i):
return get_prop(i)
@prop.setter
def prop(self, i, val):
set_prop(i, val)
Я почти уверен, что c.__setitem__ = set
неправильно, но я не могу понять, как получить ссылку на экземпляр в тот момент. Идеи?
Решение Алекса Мартелли работает на 2.6, но что-то в нем не работает на 2.4 и 2.5 (я бы предпочел, чтобы оно работало и на этих старых версиях, хотя это не является строго обязательным):
2,4
>>> p = P()
>>> p.prop
>>> p.prop[0]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unsubscriptable object
2,5
>>> p = P()
>>> p.prop
>>> p.prop[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is unsubscriptable
2,6
>>> p = P()
>>> p.prop
<__main__.c object at 0x017F5730>
>>> p.prop[0]
0