0
我想寫兩個單獨但可堆棧的裝飾器,一個用於在方法之前和之後打印對象的狀態,另一個用於在方法之後運行一些內部類測試其中也有爭論)。python - 通過堆棧裝飾器傳遞函數參數
這裏我現在嘗試的例子:如果裝飾的排序如上應用
import functools
class Dog:
def __init__(self):
self.happy = False
self.has_stick = False
def __str__(self):
n = ' ' if self.happy else ' not '
return "I'm%sa happy dog" % n
def _verbose(func):
fname = func.func_name
argnames = func.func_code.co_varnames[:func.func_code.co_argcount]
@functools.wraps(func)
def decorator(*args, **kwargs):
print "Before %s(%s):" % (fname, ', '.join(
'%s=%r' % entry
for entry in zip(argnames, args)[1:] + kwargs.items()))
print args[0]
result = func(*args, **kwargs)
print "After %s(%s):" % (fname, ', '.join(
'%s=%r' % entry
for entry in zip(argnames, args)[1:] + kwargs.items()))
print args[0]
return result
return decorator
def _test(printout):
def actual_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
self = args[0]
output = func(*args, **kwargs)
self._test_not_happy_without_stick(printout)
return output
return wrapper
return actual_decorator
def _test_not_happy_without_stick(self, printout):
if printout:
print "Is happy:", self.happy
print "Has stick:", self.has_stick
if self.happy and not self.has_stick:
print "ERROR"
@_test(True)
@_verbose
def finds_stick(self, good_stick):
print "I found a stick!"
self.happy = good_stick
self.has_stick = True
if __name__ == '__main__':
fido = Dog()
fido.finds_stick(False)
,輸出爲:
Before finds_stick(good_stick=True):
I'm not a happy dog
I found a stick!
After finds_stick(good_stick=True):
I'm a happy dog
Is happy: True
Has stick: True
但是,如果是相反的(如我想要做的),傳遞給修飾函數的參數的名稱和值將丟失,如下所示:
Before finds_stick():
I'm not a happy dog
I found a stick!
Is happy: True
Has stick: True
After finds_stick():
I'm a happy dog
如何確保裝飾器的這種堆疊不會阻止參數通過裝飾器傳遞?
另外,我會很樂意提供更多pythonic方法來解決這個問題。