什么是 Python 函数上方带“@”的装饰器?

新手上路,请多包涵

抱歉,这是一个非常广泛的问题。

下面的代码是从网上找到的一些片段。我感兴趣的关键是以@protected 开头的行——我想知道这是做什么的以及它是如何做到的?它似乎在执行 do_upload_ajax 函数之前检查是否有有效用户登录。这看起来是一种非常有效的用户身份验证方法。我不明白这个@函数的机制 - 有人可以引导我朝着正确的方向解释这将如何在现实世界中实现吗?请 Python 3 回答。谢谢。

 @bottle.route('/ajaxupload', method='POST')
@protected(check_valid_user)
def do_upload_ajax():
    data = bottle.request.files.get('data')
    if data.file:
        size = 0

原文由 Duke Dougal 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 498
2 个回答

好好 看看这个 巨大的答案/小说。这是我遇到过的最好的解释之一。

我能给出的最简短的解释是装饰器将您的函数包装在另一个返回函数的函数中。

这段代码,例如:

 @decorate
def foo(a):
  print a

如果删除装饰器语法,将等效于此代码:

 def bar(a):
  print a

foo = decorate(bar)

装饰器有时采用参数,这些参数被传递给动态生成的函数以改变它们的输出。

您应该阅读的另一个术语是 闭包,因为这是允许装饰器工作的概念。

原文由 Blender 发布,翻译遵循 CC BY-SA 3.0 许可协议

装饰器是一个将函数作为唯一参数并返回函数的函数。这有助于用相同的代码一遍又一遍地“包装”功能。

我们使用@func_name 来指定要应用于另一个函数的装饰器。

以下示例将欢迎消息添加到 fun() 返回的字符串中。以 fun() 作为参数并返回 welcome()。

 def decorate_message(fun):

    # Nested function
    def addWelcome(site_name):
        return "Welcome to " + fun(site_name)

    # Decorator returns a function
    return addWelcome

@decorate_message
def site(site_name):
    return site_name;

print site("StackOverflow")

Out[0]: "Welcome to StackOverflow"

装饰器也可用于将数据(或添加属性)附加到函数。

将数据附加到 func 的装饰器函数

def attach_data(func):
       func.data = 3
       return func

@attach_data
def add (x, y):
       return x + y

print(add(2, 3))
# 5
print(add.data)
# 3

原文由 Tushar Patil 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题