import wrapt # without argument in decorator @wrapt.decorator def logging(wrapped, instance, args, kwargs): # instance is must print "[DEBUG]: enter {}()".format(wrapped.__name__) return wrapped(*args, **kwargs) @logging def say(something): pass
使用wrapt你只需要定義一個裝飾器函式,但是函式簽名是固定的,必須是(wrapped, instance, args, kwargs)
,注意第二個引數instance
是必須的,就算你不用它。當裝飾器裝飾在不同位置時它將得到不同的值,比如裝飾在類例項方法時你可以拿到這個類例項。根據instance
的值你能夠更加靈活的調整你的裝飾器。另外,args
和kwargs
也是固定的,注意前面沒有星號。在裝飾器內部呼叫原函式時才帶星號。
如果你需要使用wrapt寫一個帶引數的裝飾器,可以這樣寫。 def logging(level): @wrapt.decorator def wrapper(wrapped, instance, args, kwargs): print "[{}]: enter {}()".format(level, wrapped.__name__) return wrapped(*args, **kwargs) return wrapper @logging(level="INFO") def do(work): pass
- http://wrapt.readthedocs.io/en/latest/quick-start.html