zoukankan      html  css  js  c++  java
  • Python Day 23 面向对象进阶(内置方法:反射,isinstance和issubclass,__str__和__repr__和其他双下方法)

    Python Day 23 面向对象进阶(内置方法:反射,isinstance和issubclass,__str__和__repr__和其他双下方法)

    反射

      python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

      使用字符串数据类型的变量名来操作一个变量的值,使用反射获取某个命名空间中的值.需要有一个变量指向这个命名空间的字符串数据类型的名字,再使用getattr获取值,如果是变量能直接获得结果,如果是函数,只能拿到内存地址,加上括号就是执行

    反射的几种用法

    使用类名反射   : 静态属性、类方法、静态方法
    使用对象名反射 :对象属性、类中的普通方法
    使用模块名反射 : 变量 函数 类
    在自己所在的文件中反射全局变量 :getattr(sys.modules[__name__],'要反射的名字')

      hasattr

        判断是否存在,返回True,False (检测是否含有某属性)

    class A:
        Name1 = 'alex'
        Name2 = 'egon'
        Name3 = 'guangtou'
        def __init__(self,name):
            self.name = name
        def func(self):
            print('in func',self.name )
    
    if hasattr(A,'Name1'):   #类名 静态属性名(字符串类型)
        print(getattr(A,'Name1'))  #类名 静态属性名(字符串类型)
    hasattr

      getattr

        获取属性

    class A:
        Name1 = 'alex'
        Name2 = 'egon'
        Name3 = 'guangtou'
        def __init__(self,name):
            self.name = name
        def func(self):
            print('in func',self.name )
    
    if hasattr(A,'Name1'):   #类名 静态属性名(字符串类型)
        print(getattr(A,'Name1'))  #类名 静态属性名(字符串类型)
    getattr

      setattr

            添加和修改属性  

    class A:
        Name1 = 'alex'
        Name2 = 'egon'
        Name3 = 'guangtou'
        def __init__(self,name):
            self.name = name
        def func(self):
            print('in func',self.name )
    
    if hasattr(A,'Name1'):
        print(getattr(A,'Name1'))
    
    print(A.__dict__)
    A.Country = '中国' #增加
    print(A.__dict__)
    A.Country = '印度' #修改
    print(A.__dict__)
    setattr(A,'Country','日本')
    print(A.__dict__)
    setattr(A,'Country','德国')
    print(A.__dict__)
    setattr

      delattr

        删除属性 

    class A:
        Name1 = 'alex'
        Name2 = 'egon'
        Name3 = 'guangtou'
        def __init__(self,name):
            self.name = name
        def func(self):
            print('in func',self.name )
    
    if hasattr(A,'Name1'):
        print(getattr(A,'Name1'))
    
    print(A.__dict__)
    delattr(A,'Name1')
    print(A.__dict__)
    delattr

    isinstance和issubclass

      isinstance

        判断对象和类的关系

    a = 10
    print(isinstance(a,int))  #判断对象类型
    
    class F:pass
    class Foo(F):pass
    
    obj = Foo()
    print(isinstance(obj,Foo)) #对象属于Foo类  True
    print(isinstance(obj,F)) #可以判断继承关系  True
    print(type(obj) is Foo) #对象属于Foo类  True
    print(type(obj) is F) #无法判断继承类 False
    isinstance

      issubclass

        判断是子类

    class F:pass
    class Foo(F):pass
    print(issubclass(Foo,F))
    print(issubclass(F,Foo))
    issubclass

    __str__和__repr__

      改变对象的字符串显示 必须返回一个str数据类型

      __str__     %s  str() print()  

      __repr__  %r  repr()

           当__str__存在时  %s 使用__str__方法,__repr__存在时  %s 使用__repr__方法,

      当__str__不存在时  %s 使用__repr__方法,__repr__存在时  %s 使用__repr__方法,

    class B:
        def __str__(self):
            return 'str : class B'
    
        def __repr__(self):
            return 'repr : class B'
    b = B()
    
    print('%s' % b)
    print('%r' % b)
    
    ==================
    str : class B   #
    repr : class B  #
    
    
    *******************************
    *******************************
    class B:
    #     def __str__(self):
    #         return 'str : class B'
    
        def __repr__(self):
            return 'repr : class B'
    b = B()
    print('%s' % b)
    print('%r' % b)
    ==================
    repr : class B
    repr : class B
    View Code
    str函数或者print函数--->obj.__str__()
    repr或者交互式解释器--->obj.__repr__()
    如果__str__没有被定义,那么就会使用__repr__来代替输出
    注意:这俩方法的返回值必须是字符串,否则抛出异常
    __str__ __repr__ 注意事项

      __format__   format()

    format_dict={
        'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
        'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
        'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
    }
    class School:
        def __init__(self,name,addr,type):
            self.name=name
            self.addr=addr
            self.type=type
    
        def __format__(self, format_spec):  # format_spec = 'nat'
            if not format_spec or format_spec not in format_dict:
                format_spec='nat'
            fmt=format_dict[format_spec]    # fmt = '{obj.name}-{obj.addr}-{obj.type}'
            return fmt.format(obj=self)
    
    s1=School('oldboy1','北京','私立')
    print(format(s1,'nat'))
    print(format(s1,'tna'))
    print(format(s1,'tan'))
    print(format(s1,'asfdasdffd'))
    __format__

    其他双下方法

      __call__

        对象加上(),可以触发这个类的__call__方法。

    class Foo:
        def __call__(self):
            print('call')
    
    Foo()() #触发类的__call__方法
    
    obj = Foo()
    obj()  # 相当于调用__call__
    
    =====================
    call
    call
    __call__

      __len__

        内置函数的len函数是依赖类中的__len__

    class Classes:
        def __init__(self,student_lst):
            self.student_lst = student_lst
        def __len__(self):return len(self.student_lst)
    
    clas = Classes(['张三','程咬金','程咬银','程咬铁','程咬钢'])  #创建一个对象
    print(len(clas.student_lst))
    print(len(clas))
    __len__
    class Wahaha:
        def __init__(self,num,name,age):
            self.num = num
            self.name = name
            self.age = age
        def __len__(self):
            return len(self.__dict__) # 某个类中有多少个属性???
    obj = Wahaha(6,'haha',7)
    print(len(obj.__dict__))
    print(len(obj))
    View Code

      __hash__ 和 __eq__  

        set 依赖 __hash__和__eq__方法来完成去重

      __hash__ 

         hash值计算

      __eq__

        比较是否值相同

    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def __eq__(self, other):
            if type(self) == type(other) and   #设置条件
                self.name == other.name and 
                self.sex == other.sex :
                return True
            else: return  False
    
    p1 = Person('egon',40,'male')
    p2 = Person('egon',50,'male')
    p3 = Person('光头',80,'male')
    print(p1==p2)  #直接比较对象
    print(p1==p3)
    __eq__
    # 两个对象 的name 和 sex相同,那么这两个对象就是相同的对象
    # 对100个对象进行去重
    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def __hash__(self):
            return hash(self.name+self.sex)
        def __eq__(self, other):
            if type(self) == type(other) and 
                self.name == other.name and 
                self.sex == other.sex :
                return True
            else: return  False
    person_lst = [Person('egon',i,'male') for i in range(100)]
    print(set(person_lst))  # hash是否相等,值是否相等  __hash__值相等,__eq__值也相等
    print(hash(person_lst[1]))
    print(hash(person_lst[2]))
    # 根据每一个对象的hash值
    __hash__ __eq__
  • 相关阅读:
    sratookit
    转录组测序
    单菌基因组测序常见问题
    微生物测序样本准备方法总结
    Review:Microbiota, metagenome, microbiome傻傻分不清
    扩增子、宏基因组测序问题集锦
    扩增子图表解读8网络图:节点OTU或类Venn比较
    扩增子图片解读7三元图
    扩增子图表解读5火山图:差异OTU的数量及变化规律
    扩增子图表解读6韦恩图:比较组间共有和特有OTU或分类单元
  • 原文地址:https://www.cnblogs.com/eailoo/p/9112993.html
Copyright © 2011-2022 走看看