📜  Python中的装饰器

📅  最后修改于: 2020-04-06 08:10:29             🧑  作者: Mango

在Python中,函数是第一类对象,这意味着

  • 函数是对象;它们可以被引用,传递给变量并从其他函数返回。
  • 函数可以在另一个函数中定义,也可以作为参数传递给另一个函数。

装饰器是Python中非常强大且有用的工具,因为它允许程序员修改函数或类的行为。装饰器允许我们包装另一个函数以扩展包装函数的行为,而无需对其进行永久性修改。
在装饰器Decorators中,将函数作为另一个函数的参数,然后在包装函数内部调用。
装饰器的语法:

@gfg_decorator
def hello_decorator():
    print("Gfg")
'''上面的代码等效于:
def hello_decorator():
    print("Gfg")
hello_decorator = gfg_decorator(hello_decorator)'''

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

装饰器可以修改行为:

# 定义一个装饰器
def hello_decorator(func):
    # inner1是一个包装函数,其中的参数被调用
    # 内部函数可以访问外部本地函数,例如本例中的“ func"
    def inner1():
        print("你好, 在函数执行之前")
        # 在包装函数内,调用函数
        func()
        print("在函数执行之后")
    return inner1
# 定义一个函数,在包装函数内被调用
def function_to_be_used():
    print("在函数内 !!")
# 传递装饰器内的'function_to_be_used'来控制行为
function_to_be_used = hello_decorator(function_to_be_used)
# 调用函数
function_to_be_used()

输出:

你好, 在函数执行之前
在函数内 !!
在函数执行之后

让我们看看上面的代码在调用“ function_to_be_used”时如何逐步运行。

让我们跳到另一个示例,在该示例中,我们可以使用装饰器轻松找出函数的执行时间

# 导入所需模块
import time
import math
# 装饰器用来计算时间
def calculate_time(func):
    # 在inner1加入参数
    def inner1(*args, **kwargs):
        # 储蓄执行前的时间
        begin = time.time()
        func(*args, **kwargs)
        # 储蓄执行后的时间
        end = time.time()
        print("总的时间: ", func.__name__, end - begin)
    return inner1

@calculate_time
def factorial(num):
    # 暂停2秒,因为总的时间很短,你可能感受不到
    time.sleep(2)
    print(math.factorial(num))
# 调用函数.
factorial(10)

输出:

3628800
总的时间: :  factorial 2.0061802864074707

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

def hello_decorator(func):
    def inner1(*args, **kwargs):
        print("执行前")
        # 获取返回值
        returned_value = func(*args, **kwargs)
        print("执行后")
        # 返回值
        return returned_value
    return inner1
# 给函数添加修饰器
@hello_decorator
def sum_two_numbers(a, b):
    print("在函数之内")
    return a + b
a, b = 1, 2
# 从函数的返回获取值
print("总和 =", sum_two_numbers(a, b))

输出:

执行前
在函数之内
执行后
总和 = 3