用于创建实用程序类的库,为类型检查和数据验证提供了良好的抽象
checktypes的Python项目详细描述
checktypes软件包
用于创建实用程序类的库,为类型提供了良好的抽象 检查和数据验证。
基本示例
创建
面向对象的api
在要继承的CheckType
旁边选择一个基类并定义一个predicate()
staticmethod或classmethod
>>>fromchecktypesimportCheckType>>>classPositiveInteger(int,CheckType):..."'int' > 0"...@staticmethod...defpredicate(n):...returnn>0...>>>classHumanAge(int,CheckType):..."'int' between 0 and 125"...minval=0...maxval=125...@classmethod...defpredicate(cls,val):...returncls.minval<=val<=cls.maxval...
或者,也可以使用lambdas来定义较短的类。
>>>classPositiveInteger(int,CheckType):..."'int' > 0"...predicate=lambdan:n>0...>>>classHumanAge(int,CheckType):..."'int' between 0 and 125"...minval=0...maxval=125...predicate=classmethod(lambdacls,n:cls.minval<=n<=cls.maxval)...
功能api
另一种方法是使用checktype()
工厂。
>>>fromchecktypesimportchecktype>>>PositiveInteger=checktype('PositiveInteger',int,lambdan:n>0,"'int' > 0")>>>HumanAge=checktype(...'HumanAge',int,doc="'int' between 0 and 125",minval=0,maxval=125,...predicate=classmethod(lambdacls,n:cls.minval<=n<cls.maxval)...)...
用法
isinstance()
超载
>>>isinstance(1,PositiveInteger)True>>>isinstance(-1,PositiveInteger)False>>>isinstance('a',PositiveInteger)False
validate()
类方法
>>>PositiveInteger.validate(1)# No output => the value is a valid one>>>PositiveInteger.validate(-1)Traceback(mostrecentcalllast):...ValueError:expected'PositiveInteger'('int'>0)butgot-1>>>PositiveInteger.validate('a')Traceback(mostrecentcalllast):...TypeError:expected'PositiveInteger'('int'>0)butgot'str'
register()
类方法
>>>isinstance(0,PositiveInteger)False>>>PositiveInteger.validate(0)Traceback(mostrecentcalllast):...ValueError:expected'PositiveInteger'('int'>0)butgot0>>>PositiveInteger.register(0)# Now let pass 0>>>isinstance(0,PositiveInteger)True>>>PositiveInteger.validate(0)
as_descriptor()
类方法
>>>classCircle:...radius=PositiveInteger.as_descriptor()...>>>c=Circle()>>>c.radius=1>>>c.radius=-1Traceback(mostrecentcalllast):...ValueError:expected'PositiveInteger'('int'>0)butgot-1for'radius'attributeof'Circle'object>>>c.radius='a'Traceback(mostrecentcalllast):...TypeError:expected'PositiveInteger'('int'>0)butgot'str'for'radius'attributeof'Circle'object
checktyped
带有类型提示(3.6+样式)的decorator
>>>fromchecktypesimportchecktyped>>>@checktyped...classPoint2D:...x:float...y:float...>>>p=Point2D()>>>p.x=0.0>>>p.y=1.0>>>p.x='a'Traceback(mostrecentcalllast):...TypeError:expected'float'butgot'str'for'x'attributeof'Point2D'object
实例化
根据概念CheckType
s最初并不打算被实例化。但既然这是一项普通的任务
为了将一个值转换成另一个类型,添加了支持以使构造函数返回一个值
与python中的标准类具有相同的规则,但有三项除外:
1-返回的值永远不是类的实例,而是一个类的实例。
>>>PositiveInteger(1)1>>>n=PositiveInteger(1)>>>print(n,type(n),sep=': ')1:<class'int'>
2-如果该值不满足isinstance()
检查,则会提高ValueError
。
>>>PositiveInteger(-1)Traceback(mostrecentcalllast):...ValueError:-1cannotbeinterpretedasa'PositiveInteger'('int'>0)
3-__init__()
和__new__()
被忽略。
>>>classMyInt(int,CheckType):...def__new__(cls,x):...return'unexpected thing'...def__init__(self,x):...self.my_attr='some value'...>>>x=MyInt(1)>>>x1>>>x.my_attrTraceback(mostrecentcalllast):...AttributeError:'int'objecthasnoattribute'my_attr'
仍然可以提供两个类属性来添加对更好实例化的支持:
1-default
如果不带参数调用类,则它提供要返回的值。
它的优点之一是:它解决了默认值不合适的问题。
>>>classNegativeInteger(int,CheckType):...default=-1...predicate=lambdan:n<0...>>>NegativeInteger()-1>>>delNegativeInteger.default>>>NegativeInteger()# int() -> 0Traceback(mostrecentcalllast):...ValueError:0cannotbeinterpretedasa'NegativeInteger'
2-factory()
它是一个可调用的,负责返回新对象。
从ABC继承时特别有用。
>>>fromcollections.abcimportSized>>>classThreePlace(Sized,CheckType):...factory=tuple...predicate=lambdas:len(s)==3...>>>ThreePlace(range(1,4))(1,2,3)>>>ThreePlace([4,5,6])(4,5,6)>>>ThreePlace('789')('7','8','9')
请注意,返回值仍将被检查。
>>>defbadfactory(*args,**kwarg):...return'bad value'...>>>ThreePlace.factory=badfactory>>>ThreePlace((1,2,3))Traceback(mostrecentcalllast):...ValueError:'bad value'cannotbeinterpretedasa'ThreePlace'>>>delThreePlace.factory>>>ThreePlace.default=0>>>ThreePlace()Traceback(mostrecentcalllast):...TypeError:'int'objectcannotbeinterpretedasa'ThreePlace'