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
しかし、それが逆になった場合(Iとして次のように装飾された関数に渡される引数の名前と値が失われます。
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
デコレータのスタッキングが、引数がデコレータを通過するのを防ぐことができないようにするにはどうすればよいですか?
また、この問題に対処するためのより平凡な方法の提案にも満足しています。