Python动态装饰器-为什么要这么多包装? [英] Python dynamic decorators - why so many wraps?
问题描述
因此,我对Python装饰器还是一种新手-以前曾经使用过它们,但我从来没有自己做过。我正在阅读本教程(该特定段落),但我没有似乎不明白为什么我们需要三个功能级别?我们为什么不能做这样的事情?
So I'm still kind of new to Python decorators - I've used them before, but I've never made my own. I'm reading this tutorial (that particular paragraph) and I don't seem to understand why do we need three levels of functions? Why can't we do something like this:
def decorator(func, *args, **kwargs):
return func(*args,**kwargs)
谢谢:)
推荐答案
那么,如果您在函数上调用该装饰器会发生什么?
Well, what would happen if you called that decorator on a function?
@decorator
def foo(): pass
此代码将立即调用我们不想要的foo。装饰器被调用,它们的返回值替换该函数。就像说
This code would immediately call foo, which we don't want. Decorators are called and their return value replaces the function. It's the same as saying
def foo(): pass
foo = decorator(foo)
因此,如果我们有一个调用foo的装饰器,我们可能希望有一个函数返回一个调用foo的函数-
So if we have a decorator that calls foo, we probably want to have a function that returns a function that calls foo -- that function that it returns will replace foo.
def decorator(f):
def g(*args, **kwargs):
return f(*args, **kwargs)
return g
现在,如果我们想将选项传递给装饰器,则无法像您的示例中那样通过函数并排准确地将它们并排传递。没有语法。因此,我们定义了一个返回参数化装饰器的函数。
Now, if we want to pass options to the decorator, we can't exactly pass them ins ide-by-side with the function like in your example. There's no syntax for it. So we define a function that returns a parameterized decorator. The decorator it returns will be a closure.
def argument_decorator(will_I_call_f):
def decorator(f):
def g(*args, **kwargs):
if will_I_call_f: return f(*args, **kwargs)
return g
return decorator
所以我们可以做到
decorator = argument_decorator(True)
@decorator
def foo(): pass
Python提供了方便的语法,可以在其中内联函数调用:
And Python offers the convenience syntax where you inline the function call:
@argument_decorator(True)
def foo(): pass
所有这些都是非装饰符
def foo(): pass
foo = argument_decorator(True)(foo)
这篇关于Python动态装饰器-为什么要这么多包装?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!