首页 > 其他分享 >自定义参数类型断言装饰器

自定义参数类型断言装饰器

时间:2023-07-11 09:15:09浏览次数:35  
标签:__ 函数 自定义 ty args 参数 kwargs 装饰 断言

代码

from inspect import signature
from functools import wraps


def typeassert(*ty_args, **ty_kwargs):
    def decorate(func):
        if not __debug__:
            return func
        sig = signature(func)  #获取函数签名
        bound_types = sig.bind_partial(*ty_args, **ty_kwargs).arguments

        @wraps(func)
        def wrapper(*args, **kwargs):
            bound_values = sig.bind(*args, **kwargs)
            for name, value in bound_values.arguments.items():
                if name in bound_types:
                    if not isinstance(value, bound_types[name]):
                        raise TypeError(
                            'Argument {} must be {}'.format(name, bound_types[name])
                        )
            return func(*args, **kwargs)
        return wrapper
    return decorate


@typeassert(int, int)
def add(x, y):
    return x+y


if __name__ == '__main__':
    print(add(1, 2))

说明

这段代码定义了一个装饰器函数typeassert,其作用是对函数的参数类型进行断言检查。

首先,我们可以看到typeassert函数接收可变数量的位置参数ty_args和关键字参数ty_kwargs,这些参数用于指定被装饰函数的参数类型。

在decorate函数内部,首先进行了一个条件判断if not __debug__:。__debug__是Python内置的一个全局变量,
当使用命令行参数-O或-OO运行代码时,__debug__的值为False,否则为True。因此,这个判断语句的作用是当代码运行在优化模式下时,直接返回被装饰的函数,不进行类型断言检查。

如果不是在优化模式下运行,那么接下来就开始进行类型断言检查。首先通过signature函数获取被装饰函数的签名对象sig。签名对象用于描述函数的参数和返回值的类型信息。

然后调用sig.bind_partial(*ty_args, **ty_kwargs)方法,将传入的ty_args和ty_kwargs参数与被装饰函数的参数进行部分绑定。
这个部分绑定的目的是为了获取被装饰函数中指定了类型的参数。

接着,定义了一个内部函数wrapper,并使用@wraps(func)装饰器将其与被装饰的函数进行绑定。这个内部函数就是最终被返回的包装函数。

wrapper函数接收任意数量的位置参数args和关键字参数kwargs,这些参数是被装饰函数的实际参数。
然后,通过sig.bind(*args, **kwargs)方法将实际参数与被装饰函数的参数进行绑定。

接下来,使用一个循环遍历bound_values.arguments,其中bound_values.arguments是一个字典,包含了实际参数的绑定值。
在循环中,依次检查绑定值对应的参数是否在bound_types字典中。

如果参数名在bound_types字典中,说明该参数在ty_args或ty_kwargs中指定了类型。然后,通过isinstance函数检查绑定值的类型是否与指定的类型匹配。
如果类型不匹配,则抛出TypeError异常,提示参数类型错误。

如果所有参数类型都通过了断言检查,那么最后返回调用被装饰函数的结果。

标签:__,函数,自定义,ty,args,参数,kwargs,装饰,断言
From: https://www.cnblogs.com/weiweivip666/p/17542860.html

相关文章

  • arcgis pro自定义ribbon
     参考:https://pro.arcgis.com/en/pro-app/2.9/get-started/customize-the-ribbon.htm......
  • 自定义hook函数
    什么是hook?——本质是一个函数,把setup函数中使用的CompositionAPI进行了封装。类似于vue2.x中的mixin。自定义hook的优势:复用代码,让setup中的逻辑更清楚易懂。 创建hook3文件夹新建usePoint.js文件(文件名以userxxx命名) app.vue<template><button@cl......
  • 重温设计模式 --- 装饰器模式
    引言装饰器模式是一种结构型设计模式,它允许在不改变原始对象的情况下,通过将其包装在一个装饰器对象中,来动态地添加额外的功能。装饰器模式的核心思想是,将一个对象放在另一个对象的外面,以给原始对象添加新的行为。这个“另一个对象”就是装饰器(Decorator),它持有一个原始对象(Compon......
  • springcloud -sentinel 用户自定义限流错误处理(仅限限流异常,其他异常请使用fallback属
    pom依赖<!--SpringCloudailibabanacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>......
  • pytest + yaml 框架 -49.allure报告自定义内容
    前言v1.4.0版本支持allure报告自定义内容用例添加allure描述用例中可以通过dynamic添加以下内容allure.dynamic.featureallure.dynamic.linkallure.dynamic.issueallure.dynamic.testcaseallure.dynamic.storyallure.dynamic.titleallure.dynamic.description在t......
  • 第3章 自定义控件2
    3强大的附加属性所以你正在构建一个令人惊喜的新应用程序,你需要一种在现有控件中没有直接支持的行为。你确信除了创建子类并为自己创建一堆工作外,没有其他方法来扩展现有的控件功能。是时候创建子类了,对吗?WPF提供了一项创新功能,称为附加属性,它可以用于向现有控件添加行为。这些......
  • Camstar表格自定义写js,实现单元格合并。
     效果: ......
  • python 执行超时装饰器
    代码:importsignalclassTimeoutError(Exception):passdeftimeout(seconds=10,error_message='Timeout'):defdecorator(func):defwrapper(*args,**kwargs):def_handle_timeout(signum,frame):raiseTi......
  • app直播源代码,自定义顶部搜索栏显示隐藏
    app直播源代码,自定义顶部搜索栏显示隐藏1、wxml代码 <viewclass="bar-box"style="height:{{navBarHeight}}px;">  <viewwx:if="{{show}}"class="level"style="margin-top:{{barHeight}}px;">    <viewclass=&......
  • elementui el-draw自定义拖拽指令
    一、问题引入场景:el-draw抽屉高度(宽度)可拖拽二、解决方案使用vue指令,el-draw打开后,插入一个元素,绑定鼠标事件实现拖拽主要代码如下/***el-drawer拖拽高度指令*/Vue.directive('el-drawer-drag-height',{bind(el,binding,vnode,oldVnode){......