zoukankan      html  css  js  c++  java
  • python全栈开发day23-面向对象高级:反射(getattr、hasattr、setattr、delattr)、__call__、__len__、__str__、__repr__、__hash__、__eq__、isinstance、issubclass

    一、今日内容总结

    1.反射

      使用字符串数据类型的变量名来操作一个变量的值。

      #使用反射获取某个命名空间中的值,

        #需要

          #有一个变量指向这个命名空间

          #字符串数据类型的名字

        #再使用getattr获取值,

          #如果变量能直接获取结果

          #如果是函数,只能拿到内存地址,加上括号就是执行

       #使用类名反射:  静态属性、类方法、静态方法

      #使用对象名反射:  对象属性、绑定对象方法

      #使用模块名反射:  变量、函数、类

      #在自己所在文件中反射全局变量:  getattr(sys.modules[__name__],'要反射的名字')

      #getattr 

      #hasattr

      #setattr

      #delattr

       

    # import mmm
    # print(mmm.a)                  # 直接使用模块调用模块中的变量
    # print(getattr(mmm,'a'))       # 使用反射调用模块中的变量a
    # print(getattr(mmm,'b'))       # 使用反射调用模块中的变量b
    # mmm.wahaha()                  # 直接使用模块调用模块中的函数
    # getattr(mmm,'wahaha')()       # 使用反射调用模块中的函数
    
    # print(mmm.QQxing)             # 直接使用模块获取类的内存地址
    # taibai = mmm.QQxing('光头')   # 实例化模块中的类
    # taibai.ADCa()                 # 实例调用方法
    # cls = getattr(mmm,'QQxing')   # 使用反射获取模块中的类
    # obj = cls('光头')             # 使用反射得到的类进行实例化
    # print(obj)
    # getattr(obj,'ADCa')()         # 使用反射调用类中的方法
    
    # hasattr ******
    # getattr ******
    # setattr ***
    # delattr *
    
    # import mmm
    
    
    class A:
        Name1 = 'alex'
        Name2 = 'egon'
        Name3 = 'guangtou'
        def __init__(self,name):
            self.name = name
        def func(self):
            print('in func',self.name)
    
    # A.Country = '中国'  # 增
    # A.Name1 = 'alex_sb' # 改
    # # setattr
    # print(A.__dict__)
    # setattr(A,'Country','印度')
    # print(A.__dict__)
    # # 'Role' = 'Person'
    # setattr(A,'Role','Person')
    # print(A.__dict__)
    # delattr(A,'Name1')
    # print(A.__dict__)
    View Code

    2.__call__

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

    class Call_test:
        def __call__(self):
            print('I AM CALL')
    
    c1 = Call_test()
    c1()
    View Code

    3.__len__

    # 内置函数len函数是依赖于类中的__len__()

    #__len__(self):
    class Wahaha:
        def __init__(self, num, age, sex):
            self.num = num
            self.age = age
            self.sex = sex
    
        def __len__(self):return len(self.__dict__)
    
    
    obj = Wahaha(3, 12, 'male')
    print(len(obj))
    View Code

    4.__str__和__repr__

      # 在没有实现__str__时,__repr__可以完全替代__str__

      # 在没有实现__repr__时,__str__不能替代__repr__

      # 在两者都实现的情况下:

        #__str__方法和str()、%s、print() 等息息相关

        #__repr__方法和repr()、%r等息息相关

       

    # 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'))
    # class A:pass
    # o=A()
    # o.name = 'a'
    # o.addr = 'b'
    # o.type = 'c'
    # print('{obj.name}-{obj.addr}-{obj.type}'.format(obj = o))
    View Code

    5.__hash__ #hash()在优化内存中起到作用

    6.__eq__

      #  是判断值是否相等的时候依赖__eq__的结果

          #  如果没有定义__eq__两个对象的值是否相等,会默认根据他们的内存地址是否相等判断

      

    # Person class
    # name age sex
    # 两个对象 的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 self.name==other.name and self.sex == other.sex:
                return True
            else:return False
    
        def __repr__(self):
            return '|'.join([self.name, str(self.age), self.sex])
    
    
    obj_li = []
    for i in range(100):
        obj_li.append(Person('alex', i, 'male'))
    
    
    print(obj_li)
    print(set(obj_li)) # hash是否相等,值是否相等  __hash__值相等,__eq__值也相等
    一个面试题深入了解__hash__和__eq__

      # set()集合去重的内部机制:先判断hash值是否相同,如不同,直接重新开辟空间存储,如相等,再通过__eq__判断值是否相同,相同则直接丢弃,不相同,则在附近开辟内存空间存储。

    7.isinstance和issubclass

    # isinstance 是判断一个对象是否属于某个类或其父类

    #issubclass是判断一个类是否是另一个类的子类,注意前后顺序,子类在前,父类在后。

     

    二、预习和扩展

    1、__del__

      # 析构方法,当对象在内存中释放时,会自动触发执行。

      #一个对象有用户级与内核级两种资源

      当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源。

    2、__slots__ (子类不继承,除非子类类定义)

    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

    class Student(object):
        __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称

     3、__module__和__class__

      #__module__表示当前操作的对象在哪个模块

      #__class__表示当前操作的对象是哪个类的实例化

    4.通过type生成类:

    # A = type('A',(object,),{'func':func})
    # a1 = A()
    # a1.func()



    A = type('A',(object,),{'func':lambda self:print(666)})
    a1 = A()
    a1.func()
  • 相关阅读:
    i春秋 可恶的黑客
    bugku 变量1
    开源Odoo ERP 13.2版本发行说明(译文+原文)
    Java数学运算
    SET DYNAMICS 365 COLORS AND LOGO USING THEMES
    Use SQL to Query Data from CDS and Dynamics 365 CE
    SAP四代增强实现:VA01销售订单复制项目文本时不需要显示文本框和回车
    ABAP 动态备份自建表数据到新表(自建表有数据的情况下要改字段长度或者其他)
    NTFS ADS(备用数据流)
    Windows RestartManeger重启管理器
  • 原文地址:https://www.cnblogs.com/wuchenggong/p/9110911.html
Copyright © 2011-2022 走看看