python 数据描述器实现类型检查

  

class Genre:
    def __init__(self,title,mold):
        self.title=title
        self.mold=mold

    def __get__(self,instance,owner):
        print('__get__',self,instance,owner)
        return instance.__dict__[self.title]

    def __set__(self,instance,value):
        print('__set__',self,instance,value)
        if not isinstance(value,(self.mold,)):
            raise TypeError('value {} is not mold {}'.format(value,self.mold))
        instance.__dict__[self.title]=value


class P:
    name=Genre('name',str)

    def __init__(self,name:str,age:int):
        self.name=name
        self.age=age

p=P('bb',33)
print(p.name,p.age,)
print(p.__dict__)

 

类中实现检查(inpsect)

import inspect
class B:
    def __init__(self,name,age):
        self.name=name
        self.age=age
        self.gauge()

    def gauge(self):
        parameters=inspect.signature(self.__class__).parameters
        if parameters['name'].annotation != inspect._empty:
            if not isinstance(self.name,parameters['name'].annotation):
                raise TypeError('value {} not type {}'.format(self.name,parameters['name'].annotation))

        if parameters['age'].annotation != inspect._empty:
            if not isinstance(self.age,(parameters['age'].annotation,)):
                raise ValueError('value {} not genre {}'.format(self.age,parameters['age'].annotation))

b=B(33,22)
print(b.__dict__)

 

class B:
    def __init__(self,name:str,age:int):
        self.gauge(((name,str),(age,int)))
        self.name=name
        self.age=age

    @staticmethod
    def gauge(params):
        for k,v in params:
            if not isinstance(k,(v,)):
                raise ModuleNotFoundError('{} not {}'.format(k,v))

b=B('44',33)

 

函数装饰器

import inspect

def gauge(fn):
    def wrapper(self,name,age):
        parameters=inspect.signature(fn).parameters
        if parameters['name'] != inspect._empty:
            if not isinstance(name,parameters['name'].annotation):
                raise BlockingIOError('{} not {}'.format(name,parameters['name'].annotation))

        if parameters['age'] != inspect._empty:
            if not isinstance(age,parameters['age'].annotaion):
                raise OverflowError('{} not {}'.format(age,parameters['age'].annotation))
        return fn(self,name,age)
    return wrapper


class B:
    @gauge
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

b=B(22,33)

 

 

class Genre:
    def __init__(self,designator,mold):
        self.d=designator
        self.mold=mold

    def __get__(self,instance,owner):
        if instance is not None:
            return instance.__dict__[self.d]
        return self

    def __set__(self,instance,value):  # 只能实例进入
        if instance is not None:
            if isinstance(value,self.mold):
                instance.__dict__[self.d]=value
            else:
                raise ChildProcessError('{} not {}'.format(value,self.mold))
        else:
            print(8888888)

import inspect
def mold_assert(cls):
    parameters=inspect.signature(cls).parameters
    print(parameters)
    for k,v in parameters.items():
        print(k,v)
        if v.annotation != v.empty:
            setattr(cls,k,Genre(k,v.annotation))
    return cls

@mold_assert
class P:
    name=Genre('name',str)
    age=Genre('age',int)

    def __init__(self,name:str,age:int):
        self.name=name
        self.age=age

p=P('ss','m')
print(p.__dict__)
# P.name=55
print(P.__dict__)

 

posted @ 2020-11-28 19:55  ascertain  阅读(94)  评论(0编辑  收藏  举报