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

Python定义带参数的装饰器举例详解

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

Python定义带参数的装饰器举例详解

1、如何定义带参数的装饰器?

        实际案例:

                实现一个装饰器,它用来检查被装饰函数的参数类型。装饰器可以通过参数指明函数参数的类型,调用时如果检测出类型不匹配则抛出异常。

# 不同的函数需要做不同的类型检查,通过参数为他们每一个定制化一个装饰器。
# @后面整体是一个函数的调用,相当于type_assert函数它会返回一个装饰器。
# 带参数的装饰器可以看成生产装饰器的工厂。
@type_assert(str, int, int)
def f(a, b, c):
    ... ...

@type_assert(y=list)    # 关键字传惨形式
def g(x, y):
    ... ...

        解决方案:

                提取函数签名:inspect.signature()

                带参数的装饰器,也就是根据参数定制化一个装饰器,可以看成生产装饰器的工厂。

                每次调用type_assert,返回一个特定的装饰器,然后用它去装饰其他函数。

2、代码演示
# _*_ encoding:utf-8 _*_
from inspect import signature


# 定义带参数装饰器,实现参数类型检查功能
def type_assert(*ty_args, **ty_kwargs):
    """生产装饰器工厂,内部定义一个装饰器"""

    # 获取函数参数和它类型之间的映射关系

    def decorator(func):
        # 获取函数参数列表
        sig = signature(func)
        # 奖建立类型映射和参数名字,绑定部分检查
        b_types = sig.bind_partial(*ty_args, **ty_kwargs).arguments

        # 根据参数列表定制化出来一个装饰器
        def wrapper(*args, **kwargs):
            dic = sig.bind(*args, **kwargs).arguments.items()
            for name, obj in dic:
                # 只有在映射关系中才做类型检查
                if name in b_types:
                    # 检查类型,如果类型不对抛出异常
                    if not isinstance(obj, b_types[name]):
                        raise TypeError('"%s" must be "%s"' 
                                        % (name, b_types[name]))
            return func(*args, **kwargs)

        return wrapper

    # 返回装饰器
    return decorator


# 测试代码
@type_assert(int, str, list)
def f(a, b, c):
    print(a, b, c)


f(1, 'abc', [1, 2, 3])
# 报错提示b必须是一个str
f(1, 2, [1, 2, 3])

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/883997.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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