python 装饰器装饰类
Python decorators, as the name suggests, are decorators for python entities. In simpler terms, it is a wrapper on an existing functionality without modifying that functionality. Now question may arise, why do we need decorator? Imagine a scenario where you are accessing a function from third party library and want to provide it some additional functionality but do not want to modify the existing function. Here comes decorator in picture. A decorator can be used by using @ annotation followed by decorator name.
顾名思义,Python装饰器是python实体的装饰器。 简单来说,它是对现有功能的包装,而无需修改该功能。 现在可能会出现问题,为什么我们需要装饰器? 想象一个场景,您正在从第三方库访问一个函数,并想为其提供一些附加功能,但又不想修改现有功能。 图片中有装饰工。 装饰器可以通过使用@注释后跟装饰器名称来使用 。
A worth mentioning information about decorators is that they are callable that take callable as an argument and return a callable. A callable in python is anything that can be called. For example, a class, a method, etc. are callable.
关于装饰器的值得一提的信息是它们是可调用的,以可调用为参数并返回可调用。 python中的callable是可以调用的任何东西。 例如,可以调用类,方法等。
Why to use decorator?
为什么要使用装饰器?
Let us use a practical scenario to use decorator. Imagine you have different functions in an application. Somehow your application is performing badly. First step to investigate the issue is by identifying the piece of code that is taking more time to process its responsibilities. To achieve it, you can add time at the start and end of method and then difference of two time objects will give execution time of that function. Simple, isn’t it? Now imagine you have 50 such functions where this modification is needed. You can always put logs separately for each function, it will work fine. Or decorator can be used that will decorate those functions with a execution time decorator. Let’s see how it can be implemented with a small example.
让我们使用一个实际的场景来使用装饰器。 假设您在应用程序中具有不同的功能。 您的应用程序以某种方式表现不佳。 调查该问题的第一步是确定需要花费更多时间来处理其职责的代码段。 为此,您可以在方法的开始和结束处添加时间,然后两个时间对象的差将为该函数提供执行时间。 很简单,不是吗? 现在,假设您有50个需要修改的函数。 您始终可以为每个功能分别放置日志,它将正常工作。 或者可以使用装饰器,该装饰器将用执行时间装饰器装饰这些功能。 让我们用一个小例子看看如何实现它。
def my_decorator(input_function):
def inner_decorator():
print "decorator start"
input_function()
print "decorator end"
return inner_decorator
def function_x():
print "I am not using decorator"
@input_function
def function_y():
print "I am using decorator"
When function_x and function_y are called, different outputs are observed:
调用function_x和function_y时,观察到不同的输出:
>>> function_x()
I am not using decorator
>>> function_y()
decorator start
I am using decorator
decorator end
function_y was using decorator and hence we see different outputs.
function_y使用的是装饰器,因此我们看到了不同的输出。
If we see my_decorator, it is taking a function as an input(which is a callable) and returns inner_decorator, which again is a callable. To log a method’s execution time, we can create a decorator like this:
如果我们看到my_decorator,则它将一个函数作为输入(可调用),并返回inner_decorator,它又是可调用的。 要记录方法的执行时间,我们可以创建一个装饰器,如下所示:
>>> def log(f):
... def decorated_function():
... from datetime import datetime
... print "Execution started at ", datetime.now()
... f()
... print "Execution completed at ", datetime.now()
... return decorated_function
...
>>> @log
... def print_odd_numbers():
... for i in range(20):
... if i % 2 == 1:
... print i,
...
>>> print_odd_numbers()
Execution started at 2016-08-23 16:17:11.965000
1 3 5 7 9 11 13 15 17 19
Execution completed at 2016-08-23 16:17:11.967000
So whichever function we want to log with execution time, it can be decorated with log decorator without explicitly adding logs for each function.
因此,无论我们要记录执行时间的哪个函数,都可以用日志装饰器修饰它,而不必为每个函数显式添加日志。
Decorating function that has arguments
装饰带有参数的函数
All the above examples depict a decorated function that doesn’t take any arguments but that may not be the case every time. Function arguments can be handled with a slight change in the above example.
以上所有示例均描述了一个经过修饰的函数,该函数不带任何参数,但并非每次都如此。 在上面的示例中,只需稍作更改即可处理函数参数。
>>> def log(f):
... def decorator(*args, **kwargs):
... from datetime import datetime
... print "Execution started at ", datetime.now()
... f(*args, **kwargs)
... print "Execution completed at ", datetime.now()
...
>>> def log(f):
... def decorator(*args, **kwargs):
... from datetime import datetime
... print "Execution started at ", datetime.now()
... f(*args, **kwargs)
... print "Execution completed at ", datetime.now()
... return decorator
...
>>> @log
... def odd_numbers(start, end):
... for i in range(start, end + 1):
... if i % 2 == 1:
... print i
...
>>> odd_numbers(1, 10)
Execution started at 2016-08-23 16:40:47.256000
1
3
5
7
9
Execution completed at 2016-08-23 16:40:47.258000
翻译自: https://www.pybloggers.com/2016/08/understanding-python-decorators/
python 装饰器装饰类