• python笔记(21)--反射和高阶内置方法


    内容目录:

    • 反射
    • 高阶内置方法

    内容回顾:

    • 命名空间:类和对象分别存在不同的命名空间中

    面向对象的三大特性:继承,多态,封装

    • 继承:
      • 单继承:(重要程度****)
        • 父类(超类,基类)
        • 子类(派生类):派生方法和派生属性
        • 子类的对象在调用方法和属性:先用自己的,没有才用父类的
      • 多继承:(面试会用到)
        • 不会超过三个父类,不要超过三层
        • 如果子类自己有就用自己的,如果没有就依次从左往后的顺序用父类的
        • 抽象类和接口类
        • 经典类和新式类:继承规则不同,深度优先和广度优先(面试****)
      • super 只能在python3中使用(面试会用到****)
        • super是根据mro广度优先顺序找上一个类
    • 多态:(面试会用到)
      • 多态和鸭子类型
    • 封装:(面试)
      • 私有的
      • __名字(双下划线变为私有属性)
      • 只能在类的内部调用,子类都无法继承
    • 三个装饰器
      • @property **** 规范,面试 #@name.stter
      • @staticmethod ***
      • @classmethod **** 当一个方法只使用了类的静态变量时,就给这个方法加上此装饰器,默认把self改为传cls参数,不能有其他参数

    内容详细:

    1.isinstance:判断对象和类的关系

    #判断结果返回bool类型
    class A:pass
    class B(A):pass
    a = A()
    print(isinstance(a,A))	#True		isinstance(对象,类)
    

    2.issubclass:判断子类和父类的关系

    #判断结果返回bool类型
    class A:pass
    class B(A):pass
    a = A()
    print(issubclass(B,A))     #True	issubclass(子类,父类)
    

    3.反射

    • 是用字符串类型的名字,去操作变量
    • 反射对象中的属性和方法:
      • hasattr
      • getattr
      • setattr
      • delattr

    3.1 getattr(重要)

    • 反射对象的属性 ---getattr(对象,属性)

      class A:
          def func(self):
              print('in func')
      
      a = A()
      a.name = 'liyanan'
      a.age = 18
      # 反射对象的属性   --getattr(对象,属性)
      ret  = getattr(a,'name')    # 通过变量名的字符串形式取到的值
      print(ret)
      
      user = input('>>>>')
      print(getattr(a,user))  #假如输入name,则执行a.name
      
    • 反射对象的方法 ---getattr(对象,方法)

      #接上
      # 反射对象的方法
      ret = getattr(a,'func') #getattr(a,'func') == a.func
      ret()
      
    • 反射类的属性

      class A:
          price = 20
          def func(self):
              print('in func')
      
      # 反射类的属性
      # A.price
      print(getattr(A,'price'))
      
    • 反射类的方法

      class A:
          price = 20
          @classmethod
          def func(self):
              print('in func')
      
      # 反射类的方法:classmethod  staticmethod
      # A.func()
      if hasattr(A,'func'):           #判断类中是否存在第二个参数的方法
          getattr(A,'func')()         #如果有就执行
      
    • 反射模块的属性

      import my      # my为自己写的其他模块
      #反射模块的属性	my.day为模块的属性
      print(getattr(my,'day'))
      
    • 反射模块的方法

      #反射模块的方法
      getattr(my,'func')()
      
    • 内置模块也能用反射

    • 反射自己模块中的变量和函数

      import sys
      # print(sys.modules['__main__'])
      year = 2019
      def login():
          print('welcome')
      
      #反射自己模块中的变量
      print(getattr(sys.modules[__name__],'year'))
      user_in = input('>>>')
      print(getattr(sys.modules[__name__],user_in))
      
      #反射自己模块中的函数
      getattr(sys.modules[__name__],'login')()
      

    3.2 hasattr

    • 与getattr配合使用,主要做判断

    • 注意参数要跟getattr保持一致

      import sys
      
      year = 2019
      
      if hasattr(sys.modules[__name__],'year'):
          print(getattr(sys.modules[__name__],'year'))
      

    3.3 setattr(了解)

    • 设置修改变量

    • setattr(对象,'要修改的属性','修改的内容')

      class A:
          pass
      
      a = A()
      setattr(a,'name','nezha')
      setattr(A,'name','taibaijinxing')
      print(a.name)           #打印nezha
      print(A.name)           #打印taibaijinxing
      

    3.4 delattr(了解)

    • 删除一个变量

      class A:
          pass
      
      a = A()
      setattr(a,'name','nezha')
      setattr(A,'name','taibaijinxing')
      
      delattr(a,'name')  
      print(a.name)   #打印taibaijinxing,因为实例化对象调用了父类的name属性
      delattr(A,'name')
      print(a.name)   #报错,没有name属性
      

    4.高阶内置方法

    • __del__方法:析构函数:在删除一个对象之前,进行的一些收尾工作

      class A:
          def __del__(self):      #析构函数:在删除一个对象之前进行一些收尾工作
              self.f.close()
      
      a = A()
      a.f = open('db.txt','r',encoding='utf-8')   # 打开文件,拿到了文件操作句柄
      del a                       #del既执行了这个方法,又删除了变量
      
    • __call__方法:实例化后的对象加括号,相当于默认执行了此方法

      class A:
          def __init__(self,name):
              self.name = name
          def __call__(self, *args, **kwargs):
              for k in self.__dict__:
                  print(k,self.__dict__[k])
      
      a = A('liyanan')()  #实例化对象后加括号相当于执行了内部的__call__方法
      #a()     结果为打印self.__dict__中的静态属性   name liyanan
      
    • item方法

      • getitem
      • setitem
      • delitem
      • 附加的delattr
      class Foo:
          def __init__(self,name,age,sex):
              self.name = name
              self.age = age
              self.sex = sex
          #getitem方法
          def __getitem__(self, item):
              if hasattr(self,item):          #判断item是否存在/传值
                  return self.__dict__[item]
          #setitem方法
          def __setitem__(self, key, value):
              self.__dict__[key] = value
          #delitem方法
          def __delitem__(self, key):
              del self.__dict__[key]
          
          #delattr方法
          def __delattr__(self, item):
              print('del obj.key时,我执行')
              self.__dict__.pop(item)
              
      f = Foo('alec','18','男')
      print(f['name'])    #f['']这种格式默认执行了类中的__getitem__方法,等于f.name
      
      f['hobby'] = 'python'   #默认调用了setitem方法,使类中的字典添加了key和value
      print(f.hobby,f['hobby'])   #结果都为python
      
      del f.hobby         #先调用类中的delattr方法,如果没有就调用object中的(直接删除)
      del f['hobby']      #默认调用了delitem方法,删除了类中的静态属性
      
    • __new__用法(面试会考)

      • 所有的类中都是先执行__new__方法,再执行__init__方法

      • 使用场景:设计模式:单例模式:只能有一个实例化对象,后面实例化的对象属性都会覆盖第一个对象的属性,如果没有覆盖则用第一个对象的属性

        #单例模式
        class A:
            __instance = False					#设置一个私有属性
            def __init__(self,name,age):
                self.name = name
                self.age = age
            def __new__(cls, *args, **kw):		#先执行new,再执行__init__方法
                if cls.__instance:
                    return cls.__instance
                cls.__instance = object.__new__(cls)
                return cls.__instance
        
        yanan = A('yanan',26)
        yanan.cloth = 'cool'
        beijing = A('beijing',23)
        print(yanan)    #<__main__.A object at 0x000001B336D38C50>
        print(beijing)  #<__main__.A object at 0x000001B336D38C50> 一样的内存地址,证明只能实例化一个对象
        print(yanan.name)       #beijing	被第二次实例化对象<北京>给覆盖了
        print(beijing.name)     #beijing	
        print(beijing.cloth)    #cool		第二次实例化对象<北京>没有覆盖,则用第一个对象的属性
        
    • __eq__方法

      • 用法:比较实例化后的对象属性是否相等

        class A:
            def __init__(self,name):
                self.name = name
            #eq方法
            def __eq__(self, other):
                if self.__dict__ == other.__dict__:
                    return True
                else:
                    return False
        
        ob1 = A('pig')
        ob2 = A('pig')
        print(ob1 == ob2)   #True
        
    • __hash__方法

      • hash()是系统的哈希用法,以对象的内存地址进行哈希的

      • __hash__可以自己控制哈希用法

        class  A:
            def __init__(self,name,sex):
                self.name = name
                self.sex = sex
            def __hash__(self):
                return hash(self.name+self.sex)
        
        a = A('agg','公')
        b = A('agg','公')
        print(hash(a))
        print(hash(b))
        #系统的哈希用法是根据内存地址处理的
        #此类中的自己写的哈希算法是根据值来处理的
        
    • 示例:

      • 实例化对象去重

        class  A:
            def __init__(self,name,sex,age):
                self.name = name
                self.sex = sex
                self.age = age
            def __eq__(self, other):
                if self.name == other.name and self.sex == other.sex:
                    return True
                return False
        
            def __hash__(self):
                return hash(self.name + self.sex)
        
        a = A('agg','公',5)
        b = A('agg','公',5)
        print(hash(a))
        print(hash(b))
        print(set((a,b)))   #去重,去除重复的实例化对象(只去重name和sex)
        
  • 相关阅读:
    MSSQL慢查询查询与统计
    SQLServer统计采集数据库相关信息
    python3 安装pymssql失败 pip3 install pymssql
    CentOS7源码安装Python3
    python3 安装pyodbc失败 pip3 install pyodbc
    Django配置Mysql数据库 (Pycharm)
    DBArtist之Oracle入门第4步: Oracle创建数据库
    DBArtist之Oracle入门第3步: 安装配置PL/SQL Developer
    linux三剑客
    python + SMTP 发送邮件
  • 原文地址:https://www.cnblogs.com/lynlearnde/p/12938803.html
Copyright © 2020-2023  润新知