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方法来解决这个问题。