Ich habe ein Problem mit der Dekoration einer nativen Liste Methoden mit Post-Hook-Funktionen. Ich brauche einen Dekorator, der als Argument eine native Listenmethode annimmt und nach dem Aufruf der Methode auch einen Code der Funktion, der dekoriert wird, ausführen soll. Dieses Stück Code funktioniert in Ordnung:Klassenmethode Hook Dekorator in Python2
def _add_hook(clsmtd, info_fcn):
def hooked(s, *p, **k):
ret = clsmtd(s, *p, **k)
'''some magic happens here'''
print info_fcn(s, *p, **k)
return ret
return hooked
def reporting_list_deco(cls):
def append_info(s, *p, **k):
return 'append to %s' % s._name
cls.append = _add_hook(cls.append, append_info)
def remove_info(s, idx, *p, **k):
return 'removin %s[%s]' % (s._name, idx)
cls.remove = _add_hook(cls.remove, remove_info)
def setitem_info(s, idx, *p, **k):
return 'setitem %s[%s]' % (s._name, idx)
cls.__setitem__ = _add_hook(cls.__setitem__, setitem_info)
''' and so on also for pop, sort, insert, reverse and extend '''
return cls
def test_reporting_list():
@reporting_list_deco
class reportin_list(list):
def __init__(self, *p, **k):
super(reportin_list, self).__init__(*p, **k)
self._name = 'foo'
rl = reportin_list([6,6,6])
rl[1] = 1
rl.append(7)
rl.remove(1)
''' outputs:
setitem foo[1]
append to foo
removin foo[1]
'''
Aber ich mag es so schreiben:
def better_reporting_list_deco(cls):
@_add_hook_for(cls.append)
def append_info(s, *p, **k):
return 'append to %s' % s._name
@_add_hook_for(cls.remove)
def remove_info(s, idx, *p, **k):
return 'removin %s[%s]' % (s._name, idx)
@_add_hook_for(cls.__setitem__)
def setitem_info(s, idx, *p, **k):
return 'setitem %s[%s]' % (s._name, idx)
return cls
Das Problem ist, dass ich weiß nicht, wie die _add_hook_for
Dekorateur zu schreiben. Bitte um Rat.
Sie könnten es vielleicht als '@_add_hook_for (cls, 'append')', indem es wie eine seltsame Verwendung eines Dekorators scheint. – jonrsharpe
@jonrsharpe: Guter Punkt. Aber fast jede der nativen Methoden hat eine andere Schnittstelle, und Reporting-Funktionen erfordern unterschiedliche Argumente. – Mikaelblomkvistsson
Wird dies immer auf integrierte Typen angewendet? Dann kann ich dies mit dem gleichen Code für Python 2 und 3 arbeiten :-) –