面向对象的反射 和 特殊内置方法

一,
反射: 用字符串数据类型的变量名来访问这个变量的值
反射方法: getattr(a,b)                               查找这个对象或者类中某个属性或者方法         ====>a是对象或类,b是字符串格式 的属性                  
      hasattr(a,b)                 检查对象,或者类是否包含某个属性,或者方法           这两个命令一般会放一块执行.   ===>a是对象或类,b是字符串格式 的属性   
      setattr(a,b,c)                  给对象添加一个属性,或者类添加一个静态变量    a是对象或类,b是原属性,c是新属性

                delattr(a,b)                                 删除对象或类的某个属性                  ========>  a是对象或类,b是字符串格式 的属性     
反射应用: (1) 类: 静态属性, 类方法,静态方法
      命名空间.名字 == getattr(命名空间,'名字')
      #这里的名字可以是类中的 (静态属性, 类方法,静态方法),相当于(类.属性名) 或者(类.方法名)
class Student:
  ROLE = 'STUDENT'
@classmethod                               这是个类方法,类调用的时候不用传参数
def check_course(cls):
  print('查看课程了')

@staticmethod                                  静态属性方法,当成普通属性调用就行,不用穿参数
def login():
  print('登录')
反射查看属性
print(Student.ROLE)
print(getattr(Student,'ROLE'))         #查看静态属性

反射调用方法
getattr(Student,'check_course')()       # 利用字符串类型的变量名调用类方法
getattr(Student,'login')()           # 利用字符串类型的变量名调用静态方法

(2) 对象: 方法,对象属性
      对象.名字 == getattr(对象,'名字)
      这里的名字可以是对象中的 (方法,对象属性),相当于(对象.属性名) 或者(对象.方法名)
class A:
  def __init__(self,name):
    self.name = name
def func(self):
  print('alex')
  p1 = A('gao')
print(getattr(p1,'name'))            #查看对象的属性 打印效果是 'gao'
getattr(a,'func')                #利用字符串类型的变量名调用对象方法 注意:如果没有这个方法,会在父类中寻找执行

(3)  模块名.名字             理解:引入的模块是一个PY文件,平时(模块名.名字)就可以调用模块中的功能,然后这个名字就能做手脚了
  import 模块                   利用命令getattr(模块名,'名字') 就可以调用模块中的方法
  getattr(模块,'名字')
(4) 自己文件.名字
      import sys
          print(sys.modules)                          # 都记录这是一个全局字典,Python启动时就加载,每当有模块导入时,
                                                                      都记录到字典中,当二次导入时会直接在字典中查找,加快效率
      getattr(sys.modules['__main__'],'名字')      #理解:sys是一个模块,导入的方法在python中都记录下来了,是个字典形式的,key是('__main__')
                            这样就能找到当前py文件的内存空间,然后 同上模块的理解就行

二,        类中的每一个双下方法都有自己的特殊意思,而且所有的双下方法没有你在外部直接调用的

             而是总有一些其他的,内置函数,特殊的语法,来自动触发这些双下方法

       (1)   __call__   相当于 对象()  

       (2)  __len__     len(obj)

       (3)  __new__    特别重要   开辟内从空间的   类的构造方法    理解:当实例化一个对象的时候,会自动执行object类中__new__方法,

                                                                                                                返回值是一个内存空间,传值__init__方法中的self.然后执行__init__......

         运行原理:

                   

 class Single:
   def __new__(cls, *args, **kwargs):
     # print('在new方法里')
     obj = object.__new__(cls)
     print('在new方法里',obj)
     return obj

  def __init__(self):
    print('在init方法里',self)

  

  单例类:如果一个类 从头到尾只能有一个实例,说明从头到尾之开辟了一块儿属于对象的空间,那么这个类就是一个单例类

                         class A:

                              _ISINSTANCE = NONE

                         def __new__(cls,*args,**kwargs) :                             #cls  表示的是A这个类名称空间

                                if  not cls.__ISINSTANCE:         #当一次实例化时,内部__ISINSTANCE为空,条件成立,   当第二次实例化,内部__ISINSTANCE不为空,条件不成立,不会再开辟空间

                                       cls.__ISINSTANCE=object.__new__(cls)     #objec通过__new__(cls)构造方法给cls也就是A开辟了一个内存空间赋值给cls.__ISINSTANCE这个内置静态属性

                                 return cls.__ISINSTANCE                                   #返回的这个类新建的对象空间   注意:当实例化一个对象后,这个返回值已经有名称空间,不再为空

                          def __init__(self,name,age):

                                 self.name = name

                                 self.age = age

       s1 = Single('alex',83)
       s2 = Single('taibai',40)
       print(s1.name)
       print(s2.name)
       print(s1,s2)

      (4)   __str__   

                           print一个对象         那就相当于调用一个对象的__str__方法

                           str(obj)强转一个对象     那就相当于执行obj.__str__方法

                            '%s' %obj                     那就相当于执行obj.__str__方法

                        

     

                                      

    

  

原文地址:https://www.cnblogs.com/laogao123/p/9393070.html