学习Python函数的高级特性:装饰器
Python的装饰器是一种用于扩展函数功能的高级特性。装饰器是一种特殊的函数,它接受一个函数作为参数,并返回一个新的函数。这样就可以在不修改原函数代码的情况下,对原函数进行功能的增强或修改。
装饰器的使用可以极大地简化我们的代码,增强代码的可读性和可维护性。下面我们来详细介绍一下Python函数的装饰器。
首先,我们来看一个简单的例子,使用装饰器实现一个简单的日志功能:
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print('2018-06-01')
now()
上述代码中,定义了一个名为log的装饰器函数,它接受一个函数作为参数,并返回一个新的函数wrapper。wrapper函数负责打印日志信息并调用原函数。
通过在函数定义的上方添加@log,就可以将log装饰器应用到now函数上。这样,调用now函数时,实际上是调用了经过装饰后的函数wrapper。
除了使用@语法糖外,还可以使用等价的写法:
def now():
print('2018-06-01')
now = log(now)
装饰器的优点之一是可以在不改变原函数代码的情况下,对其进行功能的增强。比如我们可以再给log函数增加一个参数,用来指定日志的等级:
def log(level):
def decorator(func):
def wrapper(*args, **kw):
if level == 'info':
print('[INFO] call %s():' % func.__name__)
elif level == 'warn':
print('[WARN] call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
return decorator
@log('info')
def now():
print('2018-06-01')
now()
通过给log函数增加一个参数level,并在定义wrapper函数时判断level的值,我们可以在不同的日志级别下打印不同的日志信息。
装饰器还可以进行多层嵌套,每一层都可以对原函数进行一定的修改或增强。下面是一个具有三层嵌套的装饰器的示例:
from functools import wraps
def log(level):
def decorator1(func):
@wraps(func)
def wrapper1(*args, **kw):
print('[%s] call %s():' % (level, func.__name__))
return func(*args, **kw)
return wrapper1
def decorator2(func):
@wraps(func)
def wrapper2(*args, **kw):
print('[%s] call %s():' % (level, func.__name__))
return func(*args, **kw)
return wrapper2
if level == 'debug':
return decorator1
elif level == 'info':
return decorator2
@log('debug')
def now():
print('2018-06-01')
now()
通过多层嵌套的装饰器,我们可以根据不同的level值,对原函数进行不同的处理。
需要注意的是,使用装饰器时, 在定义wrapper函数前加上@wraps(func)这一行。这是为了保留被装饰函数的元信息,比如函数名、参数列表等。这样,在调用被装饰函数时,就可以正常显示元信息,而不会显示wrapper函数的信息。
除了上述几种常见的装饰器用法外,装饰器还可以应用于类的方法、类以及函数的参数等多种情况。它们不仅可以对函数进行增强,还可以实现AOP(面向切面编程)等高级的功能。
总结起来,装饰器是一种强大的工具,它为我们提供了一种简洁、优雅的方式来扩展函数功能。在实际开发中,我们可以利用装饰器来实现日志记录、性能分析、权限验证等功能,极大地提高代码的可重用性、可拓展性和可维护性。掌握装饰器的使用方法,对于提升编程水平和开发效率都是非常有帮助的。
