Python描述器实现类型检查
来源:互联网 发布:知乎封号解封 编辑:程序博客网 时间:2024/06/06 06:38
(一)
使用描述器对赋值过程做类型检查
下述代码的简要说明:
a = A(1,’yhy’) 实例化A类的时候,self.x访问的x是类变量TypeCheck(‘a’,int),首先会初始化TypeCheck类,由于是self.x = x赋值会调用set方法,在set方法里面,instance.dict[self.srcType] = value, 就已经将赋值完成了。
a.x 取值的时候,需要self.x,同样是调用self.TypeCheck,也会初始化,初始化的时候,在init方法里面会拿到self.srcType和self.dstType的值,拿到了self.srcType和self.dstType值在get方法里面,才会知道instance__dict__[key]的key是什么,依据对应的key值取出对于的value,最后返回。因此最后拿到的是instance__dict__[key]的值
class TypeCheck: def __init__(self, srcType, dstType): self.srcType = srcType self.dstType = dstType # instance == a , cls == A def __get__(self, instance, cls): if instance is None: return self return instance.__dict__[self.srcType] def __set__(self, instance, value): if isinstance(value,self.dstType): instance.__dict__[self.srcType] = value else: raise TypeError('{} should be {}'.format(value,self.dstType))class A: # 这个a,b 作为字典的key只要不一样就行 x = TypeCheck('a',int) y = TypeCheck('b',str) def __init__(self, x, y): self.x = x self.y = ya = A(1,'yhy')print(a.x,a.y)
(二)
在装饰器中调用描述器做类型检查
下述代码的简要说明:
通过setattr魔术方法,对Person类进行了修改,这里的name作为类属性,name = TypeCheck(name, required_type),这样就将Person类进行了改造,使得Person类有了两个类变量,一个是name = TypeCheck(‘name’, required_type), 另一个是age = TypeCheck(‘age’, required_type)
因此,Person(‘yhy’,18) 初始化的时候,self.name 中的name不是实例变量而是类变量,会调用描述器TypeCheck
赋值的时候,就会调用set方法,取值的时候会调用get方法
# Python write by yhyfrom functools import wrapsclass TypeCheck: def __init__(self, srcType, dstType): self.srcType = srcType self.dstType = dstType # instance == a , cls == A def __get__(self, instance, cls): if instance is None: return self return instance.__dict__[self.srcType] def __set__(self, instance, value): if isinstance(value,self.dstType): instance.__dict__[self.srcType] = value else: raise TypeError('{} should be {}'.format(value,self.dstType))# 函数装饰器装饰的是一个Person类# 描述器描述类与描述函数是不一样的def typeassert(**kwargs): def dec(cls): for name, required_type in kwargs.items(): setattr(cls, name, TypeCheck(name, required_type)) return cls return dec@typeassert(name=str, age=int)class Person: def __init__(self, name: str, age: int): self.name = name self.age = agep = Person('yhy',18)print(p.name)
装饰器装饰的Person类变为:
# 装饰器修改后的Person类class Person: # 装饰器使得Person类多了两个类变量name和age name = TypeCheck('name',str) age = TypeCheck('age',int) def __init__(self, name: str, age: int): self.name = name self.age = age
(三)
导入inspect库,通过signature函数分析装饰器中类的参数,实现对装饰器中类的装饰
简要介绍inspect库的signature函数:
# signature库可以对获取类初始化的参数的变量名和变量类型from inspect import signatureclass A: def __init__(self, x: int, y: str): passprint(signature(A).parameters)print(signature(A).parameters.items())for key, value in signature(A).parameters.items(): print(key) # 取出类型 print(value.annotation)# print(key) 和 print(value.annotation) 的输出结果为x # 这是参数变量名<class 'int'> # 这是变量名对应的类型y<class 'str'>
通过上述的inspect库的signature函数的简要介绍,那么就可以通过signature函数获取变量名,从而实现无需给装饰器显示的传递参数,可以直接分析需要装饰的类,获取类初始化需要传递的参数名和参数的类型,在通过参数名和参数的类型装饰需要装饰的类
from inspect import signatureclass TypeCheck: def __init__(self, srcType, dstType): self.srcType = srcType self.dstType = dstType # instance == a , cls == A def __get__(self, instance, cls): if instance is None: return self return instance.__dict__[self.srcType] def __set__(self, instance, value): if isinstance(value,self.dstType): instance.__dict__[self.srcType] = value else: raise TypeError('{} should be {}'.format(value,self.dstType))def typeassert(cls): #def dec(cls): sig = signature(cls).parameters.items() for key, value in sig: setattr(cls, key, TypeCheck(key,value.annotation)) return cls #return dec@typeassertclass Person: def __init__(self, name: str, age: int): self.name = name self.age = agep = Person('yhy',25)print(p.name)print(p.age)
- Python描述器实现类型检查
- python 7-6 如何使用描述符对实例属性做类型检查,分别实现set,方法,在set内使用isinstance做类型检查
- Python检查输入类型
- python 描述器,及property 的实现
- python 实现邮件名检查
- Python参数类型检查的简单方法
- 21行python代码实现拼写检查器
- 21行python代码实现拼写检查器
- python实现拼写检查器21行轻松搞定
- Python描述器
- python 描述器协议
- Python 描述器 descriptor
- Python descriptor 描述器
- 反射检查类型是否实现某个接口
- 类型检查
- 类型检查
- python 枚举类型实现
- Python 实现简单的命名合法性检查
- 指针的*和++(--)同时出现的一些情形
- 排序2
- Windows下为64位的python3.4.3安装numpy
- python-stem Tutorial(4) 隐藏服务
- MongoOperations删除内嵌数组元素
- Python描述器实现类型检查
- LTE中的 CDF PDF 简述
- .NET多线程编程(2):System.Threading.Thread类
- fatal One or more refs for names blocks change upload
- eclipse实现热部署和热启动
- 算法导论程序22--指针和对象的实现(Python)
- WPF X:Shared概述
- 随机非线性问题的随机方法
- 计算机研究生复试上机题目:顺时针螺旋矩阵简单实现