這是爲那些問同一個問題一個很好的解釋:
# This does nothing.
class donothing(object):
def __init__(self, func):
"""
The 'func' argument is the function being decorated because in this
case, we're not instantiating the decorator class. Instead we are just
using the class object as a callable (a class is always callable as this
is how an instance is returned) to use as a decorator, which means that
it is being instantiated upon definition of the decorated function and
the decorated function is being passed in as an argument to the class's
__init__ method.
"""
self.func = func
def __call__(self, *args, **kwargs):
"""
The __call__ function is called when the decorated function is called
because the function has be eaten by the decorator class. Now it's up to
the this method to return a call to the original function. The arguments
are passed in as args, kwargs to be manipulated.
"""
# Returns original function call with original arguments.
return self.func(*args, **kwargs)
@donothing
def printer(text):
print(text)
printer('hello world')
# The printer function is now an alias for the donothing instance created, so
# the preceding was the same as:
#
# instance = donothing(printer)
# instance('hello world')
#
# Next example:
class checkforkeysinparams(object):
def __init__(self, required):
self.required = set(required)
def __call__(self, params):
def wrapper(params):
missing = self.required.difference(params)
if missing:
raise TypeError('Missing from "params" argument: %s' % ', '.join(sorted(missing)))
return wrapper
# Apply decorator class, passing in the __init__'s 'required' argument.
@checkforkeysinparams(['name', 'pass', 'code'])
def complex_function(params):
# Obviously these three are needed or a KeyError will be raised.
print(params['name'])
print(params['pass'])
print(params['code'])
# Create params to pass in. Note, I've commented out one of the required params.
params = {
'name': 'John Doe',
'pass': 'OpenSesame',
#'code': '1134',
}
# This call will output: TypeError: Missing from "params" argument: code
complex_function(params=params)
有時我認爲我對Python中的某些東西有相當好的理解,然後Alex *解釋了它,並且我意識到我突然不瞭解它。我現在不得不在週末冥想functools和肚臍皮棉的組合。 – 2010-01-09 06:00:29
@Peter,另外兩個答案將接受參數的裝飾器解釋爲類 - 在'__init__'中取出參數,然後在'__call__'中裝飾函數。這也可以,如果真實情況(arg-taking裝飾器是返回高階函數的函數 - 具體而言:返回一個函數並返回一個函數;-)感覺太奇怪了;-)。但上面的例子真的很簡單('functools.wraps'只是一個整潔的方式來保留裝飾函數的名稱和文檔字符串,以免未來內省...!)。 – 2010-01-09 06:52:40
my_decorated_function = param_checker(['req_param_1','req_param_2'])(my_decorated_function)。我不明白這一點。將聲明後的裝飾函數放置在parens中以及接下來如何響應函數調用會發生什麼? – orokusaki 2010-01-09 17:30:44