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

装饰器避免了代码中不必要的重复,在开发过程中可以预先做一些设置,比如设置计时器、日志处理等;也可以设置有效性和检查运行时。
接下来先看看简单的函数及其调用!
def greet():
print("小明,你好!")
greet_name = greet
greet_name()
输出结果:小明,你好!
从以上代码中可以看出,每项内容都是对象,可以给一个变量赋值,反之,必要的时候可以把函数作为变量的赋值。这一点对理解装饰器很重要!
下面看一个函数作为另一个函数的返回的例子:
def greet():
def greeting_at_dawn():
print("早上好!")
return greeting_at_dawn
salute = 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 5
print(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_numbers
def 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_func
def 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_decorator
def get_number():
return 5
print(get_number())
运行结果:
数值按 2 递增
数值按 1 递减
6
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/76171
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!