huin 的回答很好。他的两个选项仅在定义了装饰函数时才执行装饰器代码(这不是批评,因为通常这正是您想要的)。这是他基于类的方法的扩展,每次调用函数时也会执行一些代码。这就是你做的事情,例如,当你使用装饰器来确保线程安全时。
class MyInnerDecorator:
def __init__( self, outer_decorator, *args, **kwargs ):
self._outerDecorator = outer_decorator
self._args = args
self._kwargs = kwargs
def __call__( self, f ):
print "Decorating function\n"
self._f = f
return self.wrap
def wrap( self, *args, **kwargs ):
print "Calling decorated function"
print "Debug is ", self._outerDecorator._debug
print "Positional args to decorator: ", self._args
print "Keyword args to decorator: ", self._kwargs
print "Positional args to function call: ", args
print "Keyword args to function call: ", kwargs
return self._f( *args, **kwargs )
print "\n"
class MyDecorator:
def __init__( self, debug ):
self._debug = debug
def myFunc( self, *args, **kwargs ):
return MyInnerDecorator( self, "Wrapped by myFunc", *args, **kwargs )
def myOtherFunc( self, *args, **kwargs ):
return MyInnerDecorator( self, "Wrapped by myOtherFunc", *args, **kwargs )
bar = MyDecorator( debug=True )
@bar.myFunc( a=100 )
def spam( *args, **kwargs ):
print "\nIn spam\n"
@bar.myOtherFunc( x=False )
def eggs( *args, **kwargs ):
print "\nIn eggs\n"
spam( "penguin" )
eggs( "lumberjack" )
哪个输出这个:
Decorating function
Decorating function
Calling decorated function
Debug is True
Positional args to decorator: ('Wrapped by myFunc',)
Keyword args to decorator: {'a': 100}
Positional args to function call: ('penguin',)
Keyword args to function call: {}
In spam
Calling decorated function
Debug is True
Positional args to decorator: ('Wrapped by myOtherFunc',)
Keyword args to decorator: {'x': False}
Positional args to function call: ('lumberjack',)
Keyword args to function call: {}
In eggs