Python动态装饰器-为什么要这么多包装? [英] Python dynamic decorators - why so many wraps?

查看:55
本文介绍了Python动态装饰器-为什么要这么多包装?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆