对于传入的参数做类型检测,(类型注解)

  1 # 在init之前做判断,但是耦合度太高
  2 class Person:
  3     def __init__(self, name:str, age:int):
  4         params = ((name, str), (age, int))
  5         if not self.typecheck(params):
  6             raise TypeError
  7         self.name = name
  8         self.age = age
  9
 10     def typecheck(self, params):
 11         for p, t in params:
 12             if not isinstance(p, t):
 13                 return False
 14         return True
 15
 16 使用装饰器,使用inspect模块完成
 17
 18 import inspect
 19
 20 def typecheck(fn):
 21     def wrapper(*args, **kwargs):
 22         sig  = inspect.signature(fn)
 23         params = sig.parameters # OrderedDict([(‘self‘, <Parameter "self">), (‘name‘, <Parameter "name: str">), (‘age‘, <Parameter "age: int">)])
 24
 25         keys = list(params.keys())
 26         print(keys)
 27         values = list(params.values())
 28         print(values)
 29         # 位置参数
 30         for i, v in enumerate(args[1:]):
 31             if type(v) is not (values[1:])[i].annotation:
 32                 raise Exception(‘-------Different Tyeps‘)
 33         # 关键字参数
 34         for i, v in kwargs.items(): # i=age, v=12
 35             for key in keys:
 36                 if key == i and params[key].annotation != inspect._empty and type(v) is not params[key].annotation:
 37                     raise Exception(‘+++++++Different Types‘)
 38     return wrapper
 39
 40 class Person:
 41
 42     @typecheck  # __init__ = typecheck(__init__)
 43     def __init__(self, name:str, age:int=12):
 44         self.name = name
 45         self.age = age
 46
 47 p = Person(‘jack‘, age=12) # 没有键值对的方式
 48
 49 使用描述器 将属性放到自己的属性字典中
 50 class TypeCheck:
 51     def __init__(self, flag, type):
 52         self.flag = flag
 53         self.type = type
 54
 55     def __get__(self, instance, owner):
 56         return instance.__dict__[self.flag]
 57
 58     def __set__(self, instance, value):
 59         if isinstance(value, self.type):
 60             instance.__dict__[self.flag] = value
 61         else:
 62             raise TypeError
 63
 64
 65 class Person:
 66     name = TypeCheck(‘name‘, str)
 67     age = TypeCheck(‘age‘, int)
 68
 69     def __init__(self, name:str, age:int):
 70         self.name = name
 71         self.age = age
 72
 73 p = Person(‘tom‘, 18)
 74 print(p.name)
 75 print(p.age)
 76 print(p.__dict__)
 77
 78 使用描述器 将属性放到描述器实例的属性字典中
 79 class TypeCheck:
 80     def __init__(self, flag, type):
 81         self.flag = flag
 82         self.type = type
 83         self.data = {}
 84
 85     def __get__(self, instance, owner):
 86         # return instance.__dict__[self.flag]
 87         print(self.__dict__)
 88         return self.data[self.flag]
 89
 90     def __set__(self, instance, value):
 91         if isinstance(value, self.type):
 92             # instance.__dict__[self.flag] = value
 93             self.data[self.flag] = value
 94         else:
 95             raise TypeError
 96
 97 class Person:
 98     name = TypeCheck(‘name‘, str)
 99     age = TypeCheck(‘age‘, int)
100
101     def __init__(self, name:str, age:int):
102         self.name = name
103         self.age = age
104
105 p = Person(‘tom‘, 12)
106 print(p.name)
107 print(p.age)
108 print(p.__dict__)
109
110 上面属于硬编码,将描述器写到 逻辑代码中。
111 现在将其提取出来,作为装饰器
112 函数装饰器
113 class TypeCheck:
114     def __init__(self, flag, type):
115         self.flag = flag
116         self.type = type
117
118     def __get__(self, instance, owner):
119         return instance.__dict__[self.flag]
120
121     def __set__(self, instance, value):
122         if isinstance(value, self.type):
123             instance.__dict__[self.flag] = value
124         else:
125             raise TypeError
126
127 import inspect
128 def typeassert(cls):
129     sig = inspect.signature(cls)
130     params = sig.parameters
131     for flag, value  in params.items():
132         # cls.__dict__[flag] = TypeCheck(flag, value.annotation) # 只有实例能添加属性到字典中,通过操作字典
133         if value.annotation != inspect._empty: # 或者,value.empty
134             setattr(cls, flag, TypeCheck(flag, value.annotation))
135     return cls
136
137 @typeassert # Person=typeassert(Person)
138 class Person:
139     # name = TypeCheck(‘name‘, str)
140     # age = TypeCheck(‘age‘, int)
141     def __init__(self, name:str, age:int):
142         self.name = name
143         self.age = age
144
145 p = Person(‘tom‘, 18)
146 print(p.name)
147 print(p.age)
148 print(p.__dict__)
149
150 上面属于硬编码,将描述器写到 逻辑代码中。
151 现在将其提取出来,作为装饰器
152 类装饰器
153
154 class TypeCheck:
155     def __init__(self, flag, type):
156         self.flag = flag
157         self.type = type
158
159     def __get__(self, instance, owner):
160         return instance.__dict__[self.flag]
161
162     def __set__(self, instance, value):
163         if isinstance(value, self.type):
164             instance.__dict__[self.flag] = value
165         else:
166             raise TypeError
167
168 import inspect
169 class TypeAssert:
170     def __init__(self, cls):
171         sig = inspect.signature(cls)
172         params = sig.parameters
173         for flag, value  in params.items():
174             if value.annotation != inspect._empty: # 或者,value.empty
175                 setattr(cls, flag, TypeCheck(flag, value.annotation))
176         self.cls = cls
177
178     def __call__(self, *args, **kwargs):
179         return self.cls(*args, **kwargs)
180
181 @TypeAssert # Person=TypeAssert(Person)
182 class Person:
183     def __init__(self, name:str, age:int):
184         self.name = name
185         self.age = age
186
187 p = Person(‘tom‘, 18)
188 print(p.__dict__)
189 print(p.name)
190 print(p.age)
191 print(p.__dict__)

原文地址:https://www.cnblogs.com/JerryZao/p/9692972.html

时间: 2024-07-30 05:45:31

对于传入的参数做类型检测,(类型注解)的相关文章

安全的 类型检测 类型判断

typeof检测的问题: 在 Safari (through version 4)  检测正则表达式会返回 function instanceof 检测的问题: 跨全局对象(frame)问题     arr1(来自一个frame) instanceof Array;       返回false 其他问题: 检测一个对象是原生的还是开发者定义的 解决办法: Object.prototype.toString.call(obj) ===  "[object RegExp]" 因为每个对象有

JavaScript数据类型、类型检测函数——慕课网ArraysSimilar编程练习

基本类型 string number boolean function undefined object (null,Array,Date,window) 隐式转换与"==""===" num-string   var str=num+' ' string-num   var num=str-0 "=="进行隐式转换后判断(即判断变量里面的值) "==="直接判断(判断是不是一个东西) ( NaN!=NaN null===nu

说说javascript变量类型和变量类型检测

javascript是一种弱类型语言,它的典型例子就是即变量在使用的时候可以给它赋值任何类型.那么先来看下javascript都有那些变量类型已经它们的使用方法吧. 先来看看javascript都有那些类型吧: string --- 字符串number --- 数值boolean --- 布尔值undefined --- 未申明的变量 或 申明并未赋值null --- 空object  --- 对象function  --- 函数 这里比较有争议的是 function 类型到底要不要归属到变量类

C#中方法的参数的四种类型

C#中方法的参数有四种类型: 1. 值参数类型  (不加任何修饰符,是默认的类型) 2. 引用型参数  (以ref 修饰符声明) 3. 输出型参数  (以out 修饰符声明) 4. 数组型参数  (以params 修饰符声明) =================================================== 1. 值传递: 值类型是方法默认的参数类型,采用的是值拷贝的方式.也就是说,如果使用的是值类型,则可以在方法中更改该值,但当控制传递回调用过程时,不会保留更改的值.使用

JavaScript中类型检测

JavaScript是类型松散的,也就是说,在使用变量和函数参数之前,不会对它们进行比较已确保它们的数据类型正确. JS有五种基本数据类型:Undefined.Null.Boolean.Number和String,还有一种复杂数据类型Object. JS是不支持任何创建自定义类型的机制,所有值最终都将是上述6种数据类型之一. 对于上述6种类型的变量,可以利用typeof操作符来检测. typeof操作符可能返回下列六个字符串: "undefined"--这个值未定义,对应Undefin

【JS】类型检测

本文首发于我的个人博客 : http://cherryblog.site/ 前言 js 中的类型检测也是很重要的一部分,所以说这篇文章我们就来讲一下怎么对 JavaScript 中的基本数据类型进行检测.其实这也是在读 Zepto 源码中学习到的,所以阅读源码对我们的提升还是很有帮助的.本文基于参考了前辈们的文章之后个人理解此文写的有不当的地方,请各位大佬指正. 其实常规方法主要有四种 typeof instanceof Object.prototype.toString construcor

为什么匿名内部类参数必须为final类型

首先,这关系到java对象中的生命周期的问题. 基础数据类型和引用变量(不是被引用的对象)做局部变量时(这里是和做为变量成员变量区别,它们作为成员变量后就作为对象的一部分和对象的生命周期相同了):它们的生命中周期是有作用域的,它没有受生命周期影响这一说,但是同样在这一作用域创建的对象的生命周期并不受作用域的限制. 局部变量的生命周期与局部内部类的对象的生命周期的不一致. 内部类里面使用外部类的局部变量时,其实就是内部类的对象在使用它,内部类对象生命周期中都可能调用它,而内部类试图访问外部方法中的

为什么匿名内部类参数必须为final类型(转载)

为什么匿名内部类参数必须为final类型转自于:http://feiyeguohai.iteye.com/blog/1500108 1)  从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变量(形式参数或局部变量)是天经地义的.是很自然的 2)  为什么JAVA中要加上一条限制:只能访问final型的局部变量? 3)  JAVA语言的编译程序的设计者当然全实现:局部内部类能访问方法中的所有的局部变量

STUN: NAT 类型检测方法

STUN(Simple Transversal of UDP through NATs)[21]是RFC3489 规定的一种NAT 穿透方式,它采用辅助的方法探测NAT 的IP 和端口. STUN 的探测过程需要有一个公网IP的STUN 服务器,在NAT 后面的客户端必须和此服务器配合,互相之间发送若干个UDP数据包. UDP 包中包含有客户端需要了解的信息,比如NAT 外网IP,PORT 等等.客户端通过是否得到这个UDP 包和包中的数据判断自己的NAT 类型. 前提条件:有一个公网的Serv