Python dynamic decorators - why so many wraps?

后端 未结 2 869
终归单人心
终归单人心 2021-02-13 03:13

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

2条回答
  •  悲&欢浪女
    2021-02-13 04:02

    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)
    

提交回复
热议问题