此问题在此处已有答案:
How do I make function decorators and chain them together?(19个答案)
13天前关闭。
机构群体在13天前审核了是否重新讨论此问题,并将其关闭:
原始关闭原因未解决
抱歉,这是一个非常宽泛的问题。
下面的代码是从网络上找到的一段代码。我感兴趣的是以@protected开头的代码行--我想知道这是做什么的,它是如何做的?它似乎是在执行do_upload_ AJAX 函数之前检查一个有效的用户是否登录。这看起来是一个非常有效的用户身份验证方法。但我不明白这个@函数的机制--有人能给我一个正确的方向来解释这在真实的世界中是如何实现的吗?2 Python3请回答。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
7条答案
按热度按时间j91ykkif1#
仔细看看这个enormous answer/novel,这是我遇到的最好的解释之一。
我能给予的最简短的解释是装饰器将您的函数 Package 在另一个返回函数的函数中。
例如,以下代码:
如果您移除装饰器语法,将与以下代码等效:
装饰器有时会接受参数,这些参数被传递给动态生成的函数以改变它们的输出。
另一个你应该仔细阅读的术语是闭包,因为这是允许装饰器工作的概念。
ru9i0ody2#
装饰器是一个函数,它把一个函数作为它唯一的参数,并返回一个函数。这有助于用相同的代码一次又一次地“ Package ”功能。
我们使用@ unc_name来指定要应用于另一个函数的装饰器。
装饰器还可以用于向函数附加数据(或添加属性)。
yrefmtwq3#
装饰器语法:
相当于
但不需要重复同样的名字三次。
例如,下面是
protected()
的一个可能实现:aij0ehis4#
装饰器是一个函数,它接受另一个函数,并扩展后一个函数的行为,而不显式地修改它。Python允许"嵌套"函数,即在另一个函数中的函数。Python还允许从其他函数返回函数。
假设您的原始函数名为orig_func()。
运行这个文件,调用orig_func()并打印."wheee"。
现在,让我们说,我们想修改这个函数,在调用这个函数之前做一些事情,在调用这个函数之后也做一些事情。
所以,我们可以这样做,要么选择1,要么选择2
注意,我们没有修改orig_func,而是在函数之外做了一些修改,但是我们可能希望在调用orig_func的时候,我们可以在调用函数之前和之后做一些事情,这就是我们要做的。
我们已经达到了我们的目的。但是代价是什么呢?我们不得不修改orig_func的代码。这可能并不总是可能的,特别是当其他人写了这个函数的时候。但是我们希望当这个函数被调用的时候,它被以这样一种方式修改,即在之前和/或之后可以做一些事情。然后装饰器帮助我们做这件事。我们创建了一个装饰器,并且可以保持和以前一样的名字。这样,如果我们的函数被调用,它就被透明地修改了。我们经历了以下步骤。a.定义装饰器。在docorator中,1)编写代码在orig_func之前做一些事情,如果你想的话。2)调用orig_func来完成它的工作。3)如果你想的话,在orig_func之后写代码来做一些事情。b.创建装饰器c.调用装饰器。
下面是我们的做法。
===============================================================
注意,现在orig_unc已经通过装饰器修改过了,所以,现在当你调用orig_unc()时,它将运行my_wrapper,它将执行三个步骤,正如已经概述的。
因此,您已经修改了orig_func的功能,而没有修改orig_func的代码,这是装饰器的目的。
hjzp0vay5#
Decorator只是一个将另一个函数作为参数的函数
简单示例:
up9lanfz6#
我要用一个代码来回应这个问题。
我需要什么?:我需要修改math.sin()的定义以始终将1加到值的正弦上
**问题:**我没有math.sin()代码
**解决方案:**装饰器
**在实现装饰器之前返回math.sin(90):**0.8939966636005579
**实现装饰器后返回math.sin(90):**1.8939966636005579
6l7fqoea7#
装饰器是一个函数,它将另一个函数作为参数来更改其结果或给予其某种效果。
例如,用下面的代码:
我们可以得到下面的结果:
接下来,我们创建
minus_2()
,从sum()
的结果中减去2,如下所示:简而言之:
然后,我们可以得到下面的结果:
现在,我们可以使用
minus_2()
作为带有sum()
的装饰器,如下所示:然后,我们可以得到下面同样的结果:
接下来,我们创建
times_10()
,将minus_2()
的结果乘以10,如下所示:简而言之:
然后,我们可以得到下面的结果:
现在,我们可以使用
times_10()
作为装饰器,sum()
位于@minus_2
之上,如下所示:然后,我们可以得到下面同样的结果:
不要忘记,如果一个函数有多个如上所述的装饰器,它们将按照如下所示从下至上的顺序执行:
然后,我们可以得到与上面示例中相同的结果:
所以,如果我们改变它们的顺序如下所示:
然后,我们可以得到下面不同的结果:
最后,我们在Django中创建了下面的代码,通过
@tran
在事务中运行test()
: