面向对象 之 反射 内置方法
一、反射
what:用字符串数据类型的变量名来访问这个变量的值。
什么是字符串类型的变量名??? 举个例子
why: 反射的好处?
反射是为了增加程序的动态描述能力。通俗一些,就是可以让用户参与代码执行的决定权。

1 class A: 2 NAME = '黄麒英' 3 a1 = A() 4 print(getatter(A, 'NAME') # 此时的NMAE被 引号引起来作为 字符串被访问,得到‘黄麒英’ 这个值
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')() # 调用对象的方法
模块中:
pass
三、内置方法
what:拥有双下划线形式的特殊方法。
名称:类中的方法/内置方法/双下方法/魔术方法
why:
how:所有的双下方法没有在类的外部单独调用吧,而是伴随着一些内置函数,特殊语法自动触发这些双下方法。
__call__
对象 + ()或者类名()()相当于执行了__call__方法。

class A: def __call__(self, *args, **kwargs): print('执行call方法了') def call(self): print('执行call方法了') a = A() a() #对象()执行__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函数会报错
__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__方法。
创建一个单例类
什么事单例类???
一个类,从始至终只有一个实例化对象的就是单例类。(也就是说从始至终只开辟了一个对象空间)
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 了 而是直接打印这个对象 就可以拿到属性。