Python dynamic decorators - why so many wraps?

霸气de小男生 提交于 2019-12-09 14:38:39

问题


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)

Thanks :)


回答1:


Well, what would happen if you called that decorator on a function?

@decorator
def foo(): pass

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)

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

so we can do

decorator = argument_decorator(True)
@decorator
def foo(): pass

And Python offers the convenience syntax where you inline the function call:

@argument_decorator(True)
def foo(): pass

And all this is syntax sugar for the non-decorator syntax of

def foo(): pass
foo = argument_decorator(True)(foo)



回答2:


A decorator modifies a function by adding a wrapper to it. At the time you decorate the function, it isn't being called yet, so you don't have any arguments (or keyword arguments) to look at. All you can do for now is create a new function that will handle those arguments when it finally gets them.



来源:https://stackoverflow.com/questions/5764922/python-dynamic-decorators-why-so-many-wraps

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!