- 概述
装饰器是Python语言中经常被使用的一种特殊的语法,它可以在不改变原函数代码的情况下,动态地修改函数的行为。可以说,装饰器是Python函数式编程中非常重要的一部分。
装饰器的基本原理是使用 Python 中的闭包和函数作为第一级对象。Python 的解释器并不关心装饰器的具体实现方式,它只需要能够调用原函数即可。调用函数时,再通过装饰器实现动态功能增加。
- 装饰器的基本用法
装饰器是通过在函数之前加上 @decorator_name 这样的一行语句就完成了。这里 decorator_name 就是装饰器的名称,通常情况下,这个名称都是以函数名的形式命名的。
下面是一个最简单的装饰器的例子:
def log_decorator(func):
def wrapper():
print('calling %s' % func.__name__)
return func()
return wrapper
@log_decorator
def my_func():
print('my function running')
my_func()
执行上述代码,将会输出以下两行:
calling my_func
my function running
这里的 log_decorator 就是一个装饰器,它的功能是在原函数 my_func() 运行之前输出一行日志信息。在原函数定义之上使用 @log_decorator 装饰器,可以使用装饰器对 my_func() 进行增强函数功能。
稍微讲解一下这个装饰器的原理,当调用 my_func() 时,会首先执行 log_decorator(my_func),这个时候会将原函数作为参数传递到装饰器函数 log_decorator 中,然后返回一个新函数 wrapper。而这个新函数 wrapper 在运行的时候,会先执行一行日志输出, 然后再执行原函数 my_func 的代码。
在使用装饰器进行函数装饰时,必须注意原函数的函数名、参数以及返回值的定义都要保持不变。
- 带参数的装饰器
有时候,原函数比较复杂,需要对其进行多次装饰,此时就需要使用带参数的装饰器。对于带参数的装饰器的定义,需要在函数外层再套一层函数,再将内层函数作为实际的装饰器使用,比较复杂,但是使用起来也很简单。
下面是一个带参数的装饰器的例子:
def repeat(num):
def my_decorator(func):
def wrapper(*args, **kwargs):
for i in range(num):
print('calling %s iteration %d' %(func.__name__, i+1))
func(*args, **kwargs)
return wrapper
return my_decorator
@repeat(num=3)
def greet(name):
print(f'Hello, {name}!')
greet('Tom')
执行上述代码,将会输出以下 9 行信息:
calling greet iteration 1
Hello, Tom!
calling greet iteration 2
Hello, Tom!
calling greet iteration 3
Hello, Tom!
这个例子中 repeat 就是一个带参数的装饰器,用来在函数执行之前,按照指定次数进行多次执行,而 greet 函数则被装饰为“迭代执行”的函数。
值得注意的是,带参数的装饰器需要通过传递实参进行调用。
- 总结
通过上面的讲述,我们了解了 Python 装饰器的基本使用,包括单个装饰器和带参数的装饰器两种方式,并通过下列示例进行了解释:
- 示例一:一个最简单的装饰器
- 示例二:带参数的装饰器,支持多次执行
值得注意的是,为了编写良好的代码,装饰器应该尽量简单,只实现单一的任务,避免使代码变得复杂和难以维护。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入浅出分析Python装饰器用法 - Python技术站