Python中的装饰器

装饰师 是Python中非常强大和有用的工具,因为它允许程序员修改函数或类的行为。修饰符允许我们包装另一个函数,以扩展包装函数的行为,而无需永久性地修改它。但在深入研究装饰师之前,让我们先了解一些在学习装饰师时有用的概念。

null

第一类对象 在Python中,函数是 第一类对象 这意味着Python中的函数可以作为参数使用或传递。 第一类函数的性质:

  • 函数是对象类型的实例。
  • 可以将函数存储在变量中。
  • 可以将函数作为参数传递给另一个函数。
  • 可以从函数返回函数。
  • 您可以将它们存储在数据结构中,如哈希表、列表等…

考虑下面的例子,以便更好地理解。

例1: 将函数视为对象。

Python3

# Python program to illustrate functions
# can be treated as objects
def shout(text):
return text.upper()
print (shout( 'Hello' ))
yell = shout
print (yell( 'Hello' ))


输出:

HELLOHELLO

在上面的例子中,我们将函数shout赋给了一个变量。这将不会调用函数,而是使用一个shout引用的函数对象,并创建指向它的第二个名称yell。

例2: 将函数作为参数传递

Python3

# 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.

在上面的示例中,问候功能将另一个功能作为参数(在本例中为呼喊和耳语)。然后在函数内部调用作为参数传递的函数。

例3: 从另一个函数返回函数。

Python3

# 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

在上面的例子中,我们在另一个函数的内部创建了一个函数,然后返回了在内部创建的函数。 以上三个例子描述了理解装饰师所需的重要概念。看完之后,让我们深入了解一下装饰师。

装饰师

如上所述,装饰器用于修改函数或类的行为。在Decorators中,函数作为参数被放入另一个函数中,然后在包装器函数中调用。

Decorator的语法:

@gfg_decoratordef hello_decorator():    print("Gfg")'''Above code is equivalent to -def hello_decorator():    print("Gfg")    hello_decorator = gfg_decorator(hello_decorator)'''

在上面的代码中,gfg_decorator是一个可调用函数,将在另一个可调用函数hello_decorator函数的顶部添加一些代码,并返回包装器函数。

装饰师可以修改 行为 :

Python3

# 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 executionThis is inside the function !!This is after function execution

让我们看看上面代码的行为,当调用“function_to_be_used”时,它是如何一步一步运行的。

图片[1]-Python中的装饰器-yiteyi-C++库 图片[2]-Python中的装饰器-yiteyi-C++库

让我们跳到另一个例子,我们可以很容易地找到 函数的执行时间 使用装饰师。

Python3

# 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 )


输出:

3628800Total time taken in :  factorial 2.0061802864074707

如果一个函数返回某个内容或一个参数被传递给该函数,该怎么办?

在上述所有示例中,函数没有返回任何内容,因此没有任何问题,但可能需要返回值。

Python3

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 ExecutionInside the functionafter ExecutionSum = 3

在上面的例子中,你可能会注意到内部函数的参数有很大的不同。内部函数将参数作为*args和**kwargs,这意味着可以传递任意长度的位置参数元组或关键字参数字典。这使它成为一个通用的装饰器,可以装饰具有任意数量参数的函数。

连锁装饰师

简单地说 连锁装饰师 意味着用多个装饰器装饰一个函数。

例子:

Python3

# 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
print (num())


输出:

400

上述示例类似于将函数调用为——

decor1(decor(num))

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享