zoukankan      html  css  js  c++  java
  • 关于python反射机制和定制自己的数据类型

    关于isinstance:

    isinstance是python内置的数据类型判断函数,其作用就是判断一个数值的数据类型为和类型。

    isinstance(value,type)#返回bool类型

    关于issubclass:

    issubclass是用于基础关系的判断,一般用于判断子类是否继承自父类

    issubclass(subclass,superclass)#返回bool类型

    接下来的python内置的类的反射机制

    getattr可以用于使用字符串的方式访问

    class Add():
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def func(self):
            print('from func')
    a=Add('cris',20)
    print(getattr(a,'name'))
    返回结果为
    cris
    print(setattr())
    View Code

    当然getattr还有第三个默认参数,getattr(a,'gande','None'),当get对象不存在的时候就会返回第三个参数比如None

    setattr用字符串的形式写入变量名和值,第一个参数是对象

     1 class Add():
     2     def __init__(self,name,age):
     3         self.name=name
     4         self.age=age
     5     def func(self):
     6         print('from func')
     7 a=Add('cris',20)
     8 print(getattr(a,'name'))
     9 setattr(a,'gande','')
    10 print(a.gande)
    View Code

    delattr可以用于以字符串的方式删除字段

    class Add():
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def func(self):
            print('from func')
    a=Add('cris',20)
    print(getattr(a,'name'))
    setattr(a,'gande','')
    print(a.gande)
    print(delattr(a,'gande'))
    print(a.gande)
    View Code

    hassttr可以判断是否存在这个对象,返回bool类型

    class Add():
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def func(self):
            print('from func')
    a=Add('cris',20)
    # print(getattr(a,'gande','None'))
    # setattr(a,'gande','男')
    # print(a.gande)
    # print(delattr(a,'gande'))
    print(hasattr(a,'gande'))

    执行结果为false

    内置的attr:

    __getattr__,

    类内部的__getattr__表面上看是用来返回值的,其实只有当变量访问不存在的字段的时候才会执行这段函数

    class Add:
        def __init__(self,name):
            self.name=name
        def __getattr__(self, key):  # 属性不存在情况下才会触发这个运行
            print('这个属性不存在')
    
    a=Add('cris')
    a.gande

    因为试图访问一个不存在的对象所以执行结果为‘这个属性不存在’

    __setattr__,

    也是类中的内置函数,当实例化一个对象传入参数,或者外部写入变量和值的时候会执行这段函数

    class Add:
        def __init__(self,name):
            self.name=name
        # def __getattr__(self, key):  # 属性不存在情况下才会触发这个运行
        #     print('这个属性不存在')
        def __setattr__(self, key, value):
            print('我在写入内容')
            self.__dict__[key]=value
    a=Add('cris')

    由此可以看出这个代码是用于内部写入参数的,如果这样的话那可不可以用他来控制整个类的参数类型限制呢?我们来试试。

    class Add:
        def __init__(self,name):
            self.name=name
        # def __getattr__(self, key):  # 属性不存在情况下才会触发这个运行
        #     print('这个属性不存在')
        def __setattr__(self, key, value):
            print('我在写入内容')
            if not isinstance(value,str):
                raise TypeError('类型错误')
            self.__dict__[key]=value
    
    a=Add(123)

    当我们传入一个整形参数的时候结果发现抛出了类型错误

    __delattr__,

    当外部删除类中的字段的时候会执行这个函数

    class Add:
        def __init__(self,name):
            self.name=name
        # def __getattr__(self, key):  # 属性不存在情况下才会触发这个运行
        #     print('这个属性不存在')
        def __setattr__(self, key, value):
            print('我在写入内容')
            if not isinstance(value,str):
                raise TypeError('类型错误')
            self.__dict__[key]=value
        def __delattr__(self, item):
            print('我在删除元素')
            del self.__dict__[item]
    
    a=Add('cris')
    print(a.name)
    del a.name
    print(a.name)

    结果一目了然

    接下来我们来进入下一个环节,如何定制自己的数据类型

    1.继承的方式

    我们来定制一个自己的列表函数

    class my_list(list):
        def append(self, p_object):
            print('我在添加%s'%p_object)
            if not isinstance(p_object,int):
                raise TypeError('必须是整形')
            super().append(p_object)
    l=my_list([1,2,3,4])
    l.append('2')

    利用isinstance我们成功的限制了list函数的添加元素类型必须为int类型否则报错,以上方法是利用类的继承来实现的

    2.授权的方式

    我们来定制一个写入文件的函数,在写入内容的同时写入当前系统时间,用来模仿任务日志

    import time
    class Open:
        def __init__(self,filepath,m='r',encoding='utf8'):
            self.io=open(filepath,mode=m,encoding=encoding)
            self.filepath=filepath
            self.mode=m
            self.encoding=encoding
        def write(self,line):
            t=time.strftime('%y-%m-%d %x')
            self.io.write('%s %s'%(t,line))
        def __getattr__(self, item):
            return getattr(self.io,item)
    f=Open('001.txt','w')
    f.write('xxxxxx')

    我们来测试一下其他的功能

    class Open:
        def __init__(self,filepath,m='r',encoding='utf8'):
            self.io=open(filepath,mode=m,encoding=encoding)
            self.filepath=filepath
            self.mode=m
            self.encoding=encoding
        def write(self,line):
            t=time.strftime('%y-%m-%d %x')
            self.io.write('%s %s'%(t,line))
        def __getattr__(self,item):
            return getattr(self.io,item)
    f=Open('001.txt','w')
    f.write('xxxxxx')
    f.seek(0)
    r=Open('001.txt','r')
    print(r.read())




    用授权定制一个只能传入字符串的list
    class my_list:
        def __init__(self,list):
            self.list=[]
            self.list.extend(list)
        def append(self,value):
            if not isinstance(value,str):
                raise TypeError('必须是字符串类型')
            self.list.append(value)
        @property
        def check_cent_value(self):
            return self.list[int(len(self.list)/2)]
        def __getattr__(self, item):
            return getattr(self.list,item)
    l=my_list(['a','b','c','d','e','f'])
    print(l.check_cent_value)
    print(l.pop())

    如果你看到了这段代码又看不懂没关系,这他妈本来就是给我自己看的

     

  • 相关阅读:
    MSDN Magazine搞错了
    Visual Studio 2005中设置调试符号(Debug Symbols)
    BCB 6的问题
    吴裕雄天生自然Spring Boot使用Spring Data JPA实现人与身份证的一对一关系映射
    吴裕雄天生自然Spring BootSpring Data JPA
    吴裕雄天生自然Spring BootSpring Boot对JSP的支持
    吴裕雄天生自然Spring BootSpring Boot的异常统一处理
    吴裕雄天生自然Spring Boot使用Spring Data JPA实现Author与Article的一对多关系映射
    吴裕雄天生自然Spring Boot解决 Error creating bean with name 'entityManagerFactory' defined in class path resource
    吴裕雄天生自然Spring Boot@ExceptionHandler注解和@ControllerAdvice注解
  • 原文地址:https://www.cnblogs.com/crischou/p/6757714.html
Copyright © 2011-2022 走看看