说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
我们有时候写函数时,发现有些针对函数的功能是通用的,比如要把这个函数的执行时间显示出来,又如要想函数的 return
值优化一下显示出来。装饰器的作用就是为已经存在的对象添加额外的功能,这个功能可以应用在很多的函数上,就是函数的函数。
装饰器的强大之处就在于不修复原来函数的代码就可以实现对函数功能的扩展,典型的使用场景有权限校验、用户认证、事务处理、日志记录、性能测试、缓存等等,大大提高代码的复用性。
我们来看一个非常简单的装饰器例子。首先有一个输出参数的函数:
def foo(x):
print('foo out:', x)
# 调用函数
foo(123)
# foo out: 123
我们的需求是给这个函数执行时加上日志,开始执行和结束执行,下加写一个装饰器:
def log(func):
def decorator(*args, **kwargs):
print(f'开始执行: {func.__name__}')
func(*args, **kwargs)
print('执行结束')
return decorator
以上函数的逻辑是,定义了一个 log 函数,也就是装饰器的名字,它的参数是传入一个函数对象,log 内又定义了一个 decorator 函数,参数可以理解为接受函数 func 任意参数,在 decorator 内执行 func 函数,并在执行前后增加日志日志内容的输出。log 最终将 decorator 的执行结果返回。
我们重新给foo函数应用装饰器:
@log
def foo(x):
print('foo out:', x)
# 再次调用函数
foo('Hello world!')
'''
开始执行: foo
foo out: Hello world!
执行结束
'''
类装饰器是一种装饰器,它可以用来修改类的行为或者对类进行包装。类装饰器与函数装饰器类似,但是它们接收的参数是一个类而不是一个函数。以下是一个简单示例:
class InstanceCounter:
count = 0
def __init__(self, cls):
self.cls = cls
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
print(f"类 {self.cls.__name__} 被初始化 {self.count} 次.")
return self.cls(*args, **kwargs)
@InstanceCounter
class MyClass:
def __init__(self, x):
self.x = x
# 创建 MyClass 的多个实例
instance1 = MyClass(10)
instance2 = MyClass(20)
instance3 = MyClass(30)
'''
类 MyClass 被初始化 1 次.
类 MyClass 被初始化 2 次.
类 MyClass 被初始化 3 次.
'''
例子中,InstanceCounter 是一个类装饰器。它接收一个类作为参数,并在创建类的实例时记录实例化次数。每当实例化一个经过 InstanceCounter 装饰的类时,都会在控制台上打印出类的名称以及实例化的次数。
通过这种方式,你可以方便地跟踪程序中特定类的实例化情况,而无需修改该类的定义。
装饰器在Python中有许多实际应用场景,主要有权限校验、用户认证、事务处理、日志记录、性能测试、缓存。以下是一些常见的应用场景:
装饰器是Python中非常强大和灵活的特性,它可以用来在不修改原有代码的情况下增加新的功能或者修改现有功能,极大地提高了代码的可维护性和可扩展性。
常见的内置装饰器有三种,@property、@staticmethod、@classmethod:
更新时间:2024-03-31 07:56:47 标签:python 装饰器