我用'post hook'函數裝飾本機列表方法時遇到問題。我需要一個裝飾器,它將一個本地列表方法作爲參數,在調用方法之後,它應該運行一個正在裝飾的函數代碼。 這段代碼工作好: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]
'''
但我想它寫這樣的:
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
的問題是,我不知道該怎麼寫_add_hook_for
裝飾。請指教。
你也許可以這樣做:@_add_hook_for(cls,'append')',這看起來像是一個裝飾者的奇怪用法。 – jonrsharpe
@jonrsharpe:好點。但幾乎每個本地方法都有不同的接口,報告功能需要不同的參數。 – Mikaelblomkvistsson
這是否總是適用於內置類型?然後,我可以使用Python 2和3的相同代碼工作:-) –