栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python 装饰器

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python 装饰器

    在避免重新定义函数的同时对函数功能进行增强,接受一个函数作为参数,返回一个新的函数,可以使用@语法糖调用

1. 基本格式
def 装饰器函数(传入的函数):
    def 执行的嵌套函数(传入函数的参数):
 装饰器语句
 ...
 return 传入的函数(传入函数的参数)
 ...
 装饰器语句
    return 返回的嵌套函数

@装饰器函数
def 原函数
    原函数模块...
2. 装饰器类型 I. 无参装饰器

    这里的参数我们是针对装饰器函数本身而言的,对于函数,我们可以用*args, **kwargs直接将函数参数传入,中间的代码部分根据需要个人调整,如果需要装饰的函数是有返回值的可以另外用一个变量接收返回值并返回,否则可以直接调用函数的执行,内部不用返回

import functools


def decorate(func):

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
 """
 your code
 """
 return func(*args, **kwargs)
    return wrapper
II. 带参数的装饰器

    带参数的装饰器只需要在原来那个不带参数的装饰器基础上之上在最外层套一个函数,该函数中定义一个参数,然后嵌套函数中引用该参数即可实现。

import functools


def decorate(key):
    def real_decorate(func):
 
 @functools.wraps(func)
 def wrapper(*args, **kwargs):
     """
     your code
     """
     return func(*args, **kwargs)
 return wrapper
    return real_decorate
III. 类装饰器

    如果装饰器规则逻辑复杂,需要调用多个模块或者想要区分清晰一点,我们也可以使用类的定义来实现,我们需要将装饰器函数定义在__call__方法中,当实例调用的时候就会自动执行,以下为常见四种情况

  • 函数的参数可以在__call__中通过*args,**kwargs获取
  • 装饰器的参数可以通过init函数获取
import functools

class Decorate1:
    """
    装饰器无参
    @Decorate1b
    def test()"...  相当于调用 Decorate1(test)(*args, **kwargs)
    """
    def __init__(self, func):
 self.func = func

    def __call__(self, *args, **kwargs):
 print("无参装饰器")
 """
 your code
 """
 return self.func(*args, **kwargs)


class Decorate2:
    """
    装饰器带参数、函数带参数
    @Decorate2
    def test()"...  相当于调用 Decorate2(key)(test)(*args, **kwargs)
    """
    def __init__(self, key):
 self.key = key

    def __call__(self, func):
 def wrapper(*args, **kwargs):
     print(self.key, *args)
     return func(*args, **kwargs)
 return wrapper


@Decorate1
def test():
    print("hahahahha")


@Decorate2('带参装饰器')
def test2(a, b):
    print("hahahahha2", a, b)


if __name__ == '__main__':
    test()
    test2("a", "b")

3. 装饰器调用流程

    装饰器本质上也是函数,只不过传入参数和返回值跟一般函数有所区别,相当于高阶函数(将函数作为参数传入)和嵌套函数的结合(返回的也是函数).

def decorate(func):

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
 """
 your code
 """
 return func(*args, **kwargs)
    return wrapper

@decorate
def test(*args, **kwargs):
    pass

"""
这里的@decorate语法糖等价于decorate(test)(),多个装饰器的调用也是重复此过程,不断将函数作为
参数传递给装饰器,对装饰器的调用顺序是离函数越近越先调用
"""
  • 使用@functools.wraps(func)用于保留元信息,可以保证装饰后的函数名字不会变
  • 不论是函数装饰器还是类装饰器,只要定义好逻辑都是可以互相使用的
  • 装饰器的使用很常见,包括@property、@classmethod、以及Django、Flask中的路由转发等
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/219770.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号