我有一个python哈希,其中包含函数名称到函数的映射。我想修改每个哈希条目以调用关联的函数BUT然后也调用最终的自定义函数。这有点像退出钩子。
def original():
print "original work"
变为
def replacement():
original()
print "notify somebody..."
我的问题是我认为我正在接受我的范围等,错误,因为以下代码的输出不符合预期。也许如果我可以问是否有更好的方法来做到这一点?我想坚持修改原始的cb,因为它的第三方代码和更少的地方我改变得更好。
#!/usr/bin/python
def a():
print "a"
def b():
print "b"
def c():
print "c"
orig_fxn_cb = dict()
" basic name to function callback hash "
orig_fxn_cb['a'] = a
orig_fxn_cb['b'] = b
orig_fxn_cb['c'] = c
" for each call back routine in the hash append a final action to it "
def appendFxn(fxn_cb):
appended_fxn_cb_new = dict()
for i in orig_fxn_cb.keys():
cb = fxn_cb[i]
def fxn_tail():
cb()
print cb.__name__, "tail"
appended_fxn_cb_new[i] = fxn_tail
appended_fxn_cb_new[i]()
return appended_fxn_cb_new
" make up a modified callback hash "
xxx = appendFxn(orig_fxn_cb)
print xxx
for i in xxx:
print xxx[i]()
答案 0 :(得分:4)
你好吗:
from functools import wraps
def notifier(f):
@wraps(f)
def wrapped(*args, **kwargs)
res = f(*args, **kwargs)
print "notify somebody..."
return res
return wrapped
@notifier
def original():
print "original work"
# or: original = notifier(original)
original()
original work
notify somebody...
答案 1 :(得分:2)
您遇到的问题与您在cb
函数中使用的appendFxn
变量有关。您的内部函数定义按名称访问此值,因此它们最终都会引用相同的内部回调函数(在迭代中最后出现的那个)。
您可以使用包装函数中的默认参数来解决此问题:
def appendFxn(fxn_cb):
appended_fxn_cb_new = dict()
for i in orig_fxn_cb.keys():
cb = fxn_cb[i]
def fxn_tail(cb = cb): # fix is here!
cb()
print cb.__name__, "tail"
appended_fxn_cb_new[i] = fxn_tail
appended_fxn_cb_new[i]()
return appended_fxn_cb_new
使用默认参数将cb
的当前值绑定到内部函数中的cb
名称。这样,即使原始cb
变量设置为新值,现有函数也将保留旧值。 (如果需要,您也可以创建函数参数cb = fxn_cb[i]
并删除外部cb
变量。)
答案 2 :(得分:0)
我不知道预期的输出是什么,它似乎在这里工作正常。它用一个调用原始文件的副本替换字典中的所有函数,然后打印原始名称和“尾部”。当它取代函数时,它也会执行它们。最后,您遍历生成的字典并再次执行它们。
如果多次调用appendFxn,可能会给您带来意外行为的是for i in orig_fxn_cb.keys():
行。它引用了全局orig_fxn_cb
而不是传递的fxn_cb
参数,因此进一步调用不会更改地图中的函数。