龙空技术网

Python - 函数与装饰器Decorator的原理

程序化交易A2Z 145

前言:

今天你们对“pythondecorator模块”大约比较看重,看官们都需要剖析一些“pythondecorator模块”的相关知识。那么小编也在网上搜集了一些对于“pythondecorator模块””的相关资讯,希望你们能喜欢,姐妹们快快来学习一下吧!

本文通过实例来讲述函数与装饰器之间的关系,理解Python编程中装饰器这一概念。Python中,装饰器是针对函数而言的,都是对象,可以接受参数,也可以作为参数传递。装饰器包含另一个函数,扩展了该函数的用法,并返回该函数的值。

装饰器避免了代码中不必要的重复,在开发过程中可以预先做一些设置,比如设置计时器、日志处理等;也可以设置有效性和检查运行时。

接下来先看看简单的函数及其调用!

函数及其调用

def greet():    print("小明,你好!")    greet_name = greetgreet_name()

输出结果:小明,你好!

从以上代码中可以看出,每项内容都是对象,可以给一个变量赋值,反之,必要的时候可以把函数作为变量的赋值。这一点对理解装饰器很重要!

下面看一个函数作为另一个函数的返回的例子:

def greet():    def greeting_at_dawn():        print("早上好!")            return greeting_at_dawnsalute = greet()salute()

以上代码运行结果:早上好!

在Python编程中,内部函数可以从外部函数中返回,这是函数编程的一个基本概念。

接下来看看函数作为另一个函数的参数进行传递,

def greet_person(func):    print("你好!", end=' ')    func()def say_person():    print("小明")greet_person(say_person)

输出结果:你好! 小明

理解以上三个简单的例子,有助于在编程中正确地使用装饰器。

装饰器的工作原理

装饰器是一个函数,那么定义该函数就是定义相应的装饰器,有一个外部打包函数和一个内嵌函数。

一个装饰器的基本编码如下:

def increase_number(func):    def increase_by_one():        print("数值按 1 递增 ...")        number_plus_one = func()  + 1        return number_plus_one    return increase_by_one     def get_number():    return 5    get_new_number = increase_number(get_number)print(get_new_number())

输出结果:

数值按 1 递增 ...

6

以上代码中,外部函数increase_number就是装饰器,接收函数func; 打包函数是increase_by_one,其中包含函数get_number;该装饰器increase_number赋值给另一个变量。这就是装饰器的基本语法,但是通常会使用以下更简洁的表示方法:

def increase_number(func):    def increase_by_one():        print("数值按 1 递增 ...")        number_plus_one = func()  + 1        return number_plus_one    return increase_by_one     @increase_number    def get_number():    return 5print(get_number())

从以上代码可以看出,装饰器扩展了所需函数参数的功能。

带参数的装饰器

以下代码中,需要把多个参数传递给装饰器:

def multiply_numbers(func):    def multiply_two_numbers(num1, num2):        print("两数相乘: {} 和 {}".format(num1, num2))        return func(num1, num2)            return multiply_two_numbers@multiply_numbersdef multiply_two_given_numbers(num1, num2):    return f'{num1} * {num2} = {num1 * num2}'    print(multiply_two_given_numbers(3, 4))

运行结果:

两数相乘: 3 和 4

3 * 4 = 12

把多个参数传递给内嵌函数,可以使装饰器用起来更灵活!传递多个参数还可以用以下方法:

def decorator_func(decorated_func):    def wrapper_func(*args, **kwargs):        print(f'本函数有 {len(args)} 占位参数和 {len(kwargs)} 关键字参数')        return decorated_func(*args, **kwargs)            return wrapper_func@decorator_funcdef names_and_age(age1, age2, name1='李冰', name2='王峰'):    return f'{name1} {age1} 岁, {name2} {age2} 岁'    print(names_and_age(12, 15, name1="小明", name2="小倩"))

运行结果:

本函数有 2 占位参数和 2 关键字参数

小明 12 岁, 小倩 15 岁

以上代码中,*args 构成了一个元组,用于迭代占位参数 ,而**kwargs 构成了一个关键字的词典。

多个装饰器并用

在编程中针对某个函数,可以同时并用多个装饰器,看以下代码实例:

def increase_decorator(func):    def increase_by_two():        print('数值按 2 递增')        new_number = func()        return new_number + 2            return increase_by_two    def decrease_decorator(func):    def decrease_by_one():        print('数值按 1 递减')        new_number = func()        return new_number - 1            return decrease_by_one    @increase_decorator@decrease_decoratordef get_number():    return 5    print(get_number())

运行结果:

数值按 2 递增

数值按 1 递减

6

(本文完)

更多有关Python装饰器的用法,可阅读 python - 常用的装饰器 decorator 有哪些?

标签: #pythondecorator模块