如何在 Python 中使用装饰器?

举报
Xxy_1008 发表于 2024/09/29 16:01:01 2024/09/29
【摘要】 装饰器的概念装饰器是 Python 中的一种高级函数用法,它本质上是一个函数,用于修改其他函数(或类)的功能。装饰器可以在不修改原函数源代码的情况下,给原函数添加额外的功能,如日志记录、性能测试、权限验证等。创建简单的装饰器以下是一个简单的装饰器示例,用于在函数执行前后打印一些信息: def my_decorator(func): def wrapper(): ...
  1. 装饰器的概念
    • 装饰器是 Python 中的一种高级函数用法,它本质上是一个函数,用于修改其他函数(或类)的功能。装饰器可以在不修改原函数源代码的情况下,给原函数添加额外的功能,如日志记录、性能测试、权限验证等。
  2. 创建简单的装饰器
    • 以下是一个简单的装饰器示例,用于在函数执行前后打印一些信息:
   def my_decorator(func):
       def wrapper():
           print('Before function call')
           func()
           print('After function call')
       return wrapper
  • 在这个示例中,my_decorator是一个装饰器函数,它接受一个函数func作为参数,并返回一个新的函数wrapperwrapper函数在调用原函数func之前和之后分别打印了一些信息。


  1. 应用装饰器到函数
    • 有两种常见的方式来应用装饰器到函数上。
    • 使用@语法糖(推荐)
   @my_decorator
   def my_function():
       print('Function is running')


  • 这种方式等同于my_function = my_decorator(my_function)。当定义my_function函数时,通过@my_decoratormy_decorator装饰器应用到my_function上,所以当调用my_function时,实际上执行的是my_decorator返回的wrapper函数。
  • 直接调用装饰器函数
   def my_function():
       print('Function is running')

   my_function = my_decorator(my_function)


  • 这里先定义了my_function,然后通过将my_function作为参数传递给my_decorator函数,并将返回的结果重新赋值给my_function来应用装饰器。


  1. 装饰器带参数的函数
    • 如果要装饰的函数带有参数,那么装饰器内部的wrapper函数也需要接受这些参数。例如:
   def my_decorator(func):
       def wrapper(*args, **kwargs):
           print('Before function call')
           result = func(*args, **kwargs)
           print('After function call')
           return result
       return wrapper

   @my_decorator
   def add_numbers(a, b):
       return a + b


  • 在这个示例中,add_numbers函数接受两个参数ab。装饰器中的wrapper函数使用*args*kwargs来接收任意数量的位置参数和关键字参数,这样它就可以正确地调用原函数add_numbers并传递参数。


  1. 多个装饰器的应用
    • 一个函数可以应用多个装饰器。多个装饰器的应用顺序是从下往上的(离函数定义最近的装饰器先应用)。例如:
   def decorator1(func):
       def wrapper():
           print('Decorator 1 - Before')
           func()
           print('Decorator 1 - After')
           return wrapper

   def decorator2(func):
       def wrapper():
           print('Decorator 2 - Before')
           func()
           print('Decorator 2 - After')
           return wrapper

   @decorator1
   @decorator2
   def my_function():
       print('Function is running')


  • 当调用my_function时,首先decorator2被应用,然后decorator1被应用到已经被decorator2装饰过的函数上。所以执行顺序是先执行decorator2中的Before部分,然后是decorator1中的Before部分,接着是my_function本身,然后是decorator1中的After部分,最后是decorator2中的After部分。


  1. 装饰类的装饰器
    • 装饰器也可以用于类。以下是一个简单的装饰类的装饰器示例:
   def class_decorator(cls):
       class WrapperClass:
           def __init__(self, *args, **kwargs):
               self.wrapped = cls(*args, **kwargs)

           def __getattr__(self, attr):
               return getattr(self.wrapped, attr)
       return WrapperClass

   @class_decorator
   class MyClass:
       def method(self):
           print('MyClass method')


  • 在这个示例中,class_decorator装饰器接受一个类cls作为参数,并返回一个新的类WrapperClassWrapperClass在实例化时会实例化原类cls,并且在访问属性或方法时会代理到原类的实例上。这样就可以在不修改原类定义的情况下,对类的实例化和属性访问等行为进行修改。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。