[英]How to mix *args, **kwargs and named arguments in decorator
我想創建一個自定義的裝飾器,稱為captain_hook
。 它應該存儲hooks
(要在修飾的函數之前調用的函數)並調用它們:
def captain_hook(func):
def closure(hooks=[], *args, **kwargs):
for hook in hooks:
hook(*args, **kwargs)
return func(*args, **kwargs)
return closure
現在我可以說:
@captain_hook
def sum(a, b):
return a+b
sum.__defaults__[0].append(lambda arg: sys.stdout.write(str(arg))) #this lambda function prints argument
sum(1, 2) #should write (1, 2) and return 3
問題是我無法將參數傳遞給closure
,導致args
第一個元素錯誤地解壓縮到hooks
參數: sum(1, 2)
設置hook=1
, a=2
, b - undefined
。 我怎么做?
修改__defaults__
是一種處理此問題的非常可疑的方法。 __defaults__
用於參數默認值。 如果您的鈎子不作為參數傳遞,則不應將其存儲為參數默認值。
如果您確實希望以后能夠修改鈎子,則應使裝飾器成為一個將鈎子自身存儲的類。 這是一個例子:
class CaptainHook(object):
def __init__(self, func):
self.hooks = []
self.func = func
def __call__(self, *args, **kwargs):
for hook in self.hooks:
hook(*args, **kwargs)
return self.func(*args, **kwargs)
然后:
>>> @CaptainHook
... def sum(a, b):
... return a+b
>>> sum(1, 2)
3
>>> def aHook(*args, **kwargs):
... print "I am a hook!"
>>> sum.hooks.append(aHook)
>>> sum(1, 2)
I am a hook!
3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.