Your browser does not support the Canvas element.

面向对象 之 反射 内置方法

一、反射

what:字符串数据类型的变量名来访问这个变量的值。

   什么是字符串类型的变量名???            举个例子

why: 反射的好处?

   反射是为了增加程序的动态描述能力。通俗一些,就是可以让用户参与代码执行的决定权。

  

1 class A:
2     NAME = '黄麒英'
3 a1 = A()
4 print(getatter(A, 'NAME')    # 此时的NMAE被 引号引起来作为 字符串被访问,得到‘黄麒英’ 这个值
View Code

where:  用在什么地方?

   类中:

   1、静态属性

   2、类方法

   3、静态方法

   对象中:

   1、对象

   2、对象属性

   模块中:

 

how: 怎么用?

   反射方法: hasattr    getattr    setattr    delattr       (hasattr     和  getattr   经常配对出现保证安全性,常用。)

   类中:

 

  class Teacher:
      ROLE = 'TEACHER'
  
      @ classmethod
      def check_student()    
          print('查看学生')
  
      @ staticmethod
      def check_course()
         print('查看课程')
 t1 = Teacher()
 
 print(getatter(Teacher, 'ROLE')      # 反射查看类中静态属性
 geratter(Teacher,'check_student')()   # 反射查看类方法
 getatter(Teacher,check_course') ()    # 反射查看静态方法
 
 num = input('>>>')
 if hasatter(Teacher, num)        # 通过hasatter 对num进行判断,通过是否是类中的方法,输出结果。
     getatter(Teacher, num)()
反射在类中的应用

 

  对象中 

class A:
    def __init__(self, name):
        self.name = name
        self.age = '九千岁'

    def fn(self):
        print('万岁爷')


a1 = A('魏忠贤')
print(getattr(a1, 'name'))          # 调用对象的属性
print(getattr(a1, 'age'))             
getattr(a1, 'fn')()                      # 调用对象的方法
View Code

   模块中:

  pass

三、内置方法

what:拥有双下划线形式的特殊方法。

   名称:类中的方法/内置方法/双下方法/魔术方法

why:

how:所有的双下方法没有在类的外部单独调用吧,而是伴随着一些内置函数,特殊语法自动触发这些双下方法。

 

  __call__    

  对象 + ()或者类名()()相当于执行了__call__方法。

 

class A:
    def __call__(self, *args, **kwargs):
        print('执行call方法了')

    def call(self):
        print('执行call方法了')
a = A()      
a()     #对象()执行__call__方法
__call__

 

class A:
    def __call__(self, *args, **kwargs):        #  4
        print('执行call方法了')                           #  5、 打印‘执行了call方法’

    def call(self):
        print('执行call方法了')


class B:
    def __init__(self, cls):
        print('在实例化A之前做一些事情')
        self.a = cls()                #    2、给A实例化 A()
        self.a()                        #    3、A()() 执行__call__方法
        print('在实例化A之后做一些事情')    #  6、打印
B(A)                           #     1、实例化对象并在B类传了A做参数

 

 

  __len__      

class mylist:
    def __init__(self):
        self.lst = [1, 2, 3, 4, 5, 6]
        self.name = 'alex'
        self.age = 83

    def __len__(self):
        print('执行__len__了')
        return len(self.__dict__)


l = mylist()
print(len(l))

# len(obj)相当于调用了这个obj的__len__方法
# __len__方法return的值就是len函数的返回值
# 如果一个obj对象没有__len__方法,那么len函数会报错
__len__内置方法

 

  __new__      

  属于构造方法。开辟一个空间,这个空间是属于对象的。

    在面向对象中,创建一个类,当实例化一个对象的时候会执行__init__方法,这是对象空间会被开辟出来

    那是谁开辟的这个空间呢???           就是 __new__ 这个双下方法。

     __new__方法什么时候执行???       在实例化对象之后,执行__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)


obj = Single()

 # 实例化对象 obj 。
 # 此时会找Single 中的new 方法。Single 中没有,所以用object中的__new__方法,开辟obj的对象空间,并将这个对象传给self,执行__init__方法。
__new__使用

   创建一个单例类

  什么事单例类???

  一个类,从始至终只有一个实例化对象的就是单例类。(也就是说从始至终只开辟了一个对象空间)

class A:
    __ISINSTANCE = None               # 创建一个静态属性 为None
    def __new__(cls,*args, **kwargs)        
        if not cls.__ISINSTANCE:                  # 判断。如果是True 就将实例化对象写进去,如果是False 就不写。
            cls.__ISINSTANCE = object.__new__(cls)
        return cls.__ISINSTANCE                # 将 cls.__ISINSTANCE 返回给self.
    def __init__(self, name, age)
        self.name = name
        self.age = age
a1 = A('swith', 22)
a2 = A('wto', 33)

  __str__

  print  一个对象相当于执行了__str__方法。

  str(obj) 相当于执行了obj.__str__方法。

  %s %(obj) 相当于执行了obj.__str__方法。

class Person:
    def __str__(self)
        return '%s,%s'% (self.name,self.age)

    def __init__(self, name, age)
        self.name = name 
        self.age = age


a1 = Person('林冲', 35)
print(a1)                # 此时就不用打印a1.name  a1.age 了 而是直接打印这个对象 就可以拿到属性。

 

 

   

posted @ 2018-07-30 21:08  一根小菜  阅读(197)  评论(0)    收藏  举报
Your browser does not support the Canvas element.