Decorators是 Python 中非常强大且有用的工具,因为它允许程序员修改函数或类的行为。Decorators允许我们包装另一个函数以扩展被包装函数的行为,而无需永久修改它。但在深入研究Decorators之前,让我们先了解一些在学习Decorators时派上用场的概念。
请考虑以下示例以更好地理解。
示例 1:将函数视为对象。
# Python program to illustrate functions # can be treated as objects def shout(text): return text.upper() print(shout('Hello')) yell = shout print(yell('Hello'))
输出:
HELLO HELLO
在上面的例子中,我们将函数shout分配给了一个变量。这不会调用该函数,而是获取由喊叫引用的函数对象并创建指向它的第二个名称,喊叫。
示例 2:将函数作为参数传递
# Python program to illustrate functions # can be passed as arguments to other functions def shout(text): return text.upper() def whisper(text): return text.lower() def greet(func): # storing the function in a variable greeting = func("""Hi, I am created by a function passed as an argument.""") print (greeting) greet(shout) greet(whisper)
HI, I AM CREATED BY A FUNCTION PASSED AS AN ARGUMENT. hi, i am created by a function passed as an argument.
在上面的示例中,greet 函数采用另一个函数作为参数(在本例中为 shout 和 Whisper)。然后,作为参数传递的函数在函数greet 中被调用。
示例 3:从另一个函数返回函数。
# Python program to illustrate functions # Functions can return another function def create_adder(x): def adder(y): return x+y return adder add_15 = create_adder(15) print(add_15(10))
25
在上面的示例中,我们在另一个函数内部创建了一个函数,然后返回了在内部创建的函数。 上面的三个例子描述了理解 Decorator所需的重要概念。了解完它们之后,现在让我们深入了解Decorators。
如上所述, Decorator用于修改函数或类的行为。在Decorators中,函数被作为另一个函数的参数,然后在包装函数内部调用。
Decorator的语法:
@gfg_decorator def hello_decorator(): print("Gfg") '''Above code is equivalent to - def hello_decorator(): print("Gfg") hello_decorator = gfg_decorator(hello_decorator)'''
在上面的代码中,gfg_decorator是一个可调用函数,它将在另一个可调用函数hello_decorator函数的顶部添加一些代码并返回包装函数。
Decorators可以修改行为:
# defining a decorator def hello_decorator(func): # inner1 is a Wrapper function in # which the argument is called # inner function can access the outer local # functions like in this case "func" def inner1(): print("Hello, this is before function execution") # calling the actual function now # inside the wrapper function. func() print("This is after function execution") return inner1 # defining a function, to be called inside wrapper def function_to_be_used(): print("This is inside the function !!") # passing 'function_to_be_used' inside the # decorator to control its behaviour function_to_be_used = hello_decorator(function_to_be_used) # calling the function function_to_be_used()
Hello, this is before function execution This is inside the function !! This is after function execution
让我们看看上面代码的行为以及当“function_to_be_used”被调用时它是如何逐步运行的。
让我们跳到另一个例子,我们可以使用Decorators轻松找出函数的执行时间。
# importing libraries import time import math # decorator to calculate duration # taken by any function. def calculate_time(func): # added arguments inside the inner1, # if function takes any arguments, # can be added like this. def inner1(*args, **kwargs): # storing time before function execution begin = time.time() func(*args, **kwargs) # storing time after function execution end = time.time() print("Total time taken in : ", func.__name__, end - begin) return inner1 # this can be added to any function present, # in this case to calculate a factorial @calculate_time def factorial(num): # sleep 2 seconds because it takes very less time # so that you can see the actual difference time.sleep(2) print(math.factorial(num)) # calling the function. factorial(10)
3628800 Total time taken in : factorial 2.0061802864074707
在上述所有示例中,函数没有返回任何内容,因此不存在问题,但可能需要返回值。
def hello_decorator(func): def inner1(*args, **kwargs): print("before Execution") # getting the returned value returned_value = func(*args, **kwargs) print("after Execution") # returning the value to the original frame return returned_value return inner1 # adding decorator to the function @hello_decorator def sum_two_numbers(a, b): print("Inside the function") return a + b a, b = 1, 2 # getting the value through return of the function print("Sum =", sum_two_numbers(a, b))
before Execution Inside the function after Execution Sum = 3
在上面的示例中,您可能会注意到内部函数的参数存在显着差异。内部函数将参数作为 *args 和 **kwargs,这意味着可以传递任意长度的位置参数元组或关键字参数字典。这使得它成为一个通用的Decorators,可以装饰具有任意数量参数的函数。
简单来说, chaining decorators意味着用多个Decorators来装饰一个函数。
例子:
# code for testing decorator chaining def decor1(func): def inner(): x = func() return x * x return inner def decor(func): def inner(): x = func() return 2 * x return inner @decor1 @decor def num(): return 10 @decor @decor1 def num2(): return 10 print(num()) print(num2())
400 200
上面的示例类似于将函数调用为 –
decor1(decor(num)) decor(decor1(num2))
原文链接:codingdict.net