目录 面对对象知识点 isinstance和type的区别 反射(自省) 元类 面对对象知识点 isinstance和type的区别 ? 当我们创建一个自定义类时,判断数据类型时,isinstance会判断子类即其父类时为True,
目录
- 面对对象知识点
- isinstance和type的区别
- 反射(自省)
- 元类
面对对象知识点
isinstance和type的区别
? 当我们创建一个自定义类时,判断数据类型时,isinstance会判断子类即其父类时为True,而type只判断为当前子类。
class A: pass class B(A): pass b = B() #isinstance的应用 print(isinstance(b,A)) #True print(isinstance(b,B)) #True #type的应用 print(type(b)==B) #True print(type(b)==A) #False
反射(自省)
class A: count = 6 def run(self): print('run') f = A() #1.hasattr(判断类对象是否存在指定方法和属性) print(hasattr(f,'count')) # True print(hasattr(f,'run')) # True #2.getattr(获得对象的属性和方法) print(getattr(f,'count')) # 6 getattr(f,'run')() # run #3.setattr(修改对象属性) setattr(f,'count',5) print(getattr(f,'count')) # 5 #4.delattr(删除对象属性) delattr(f,'count')
元类
? 元类:一个造类的过程,元类》》元类实例化( ) = 类》》类》》类实例化( )=对象
- type关键字造类
#第一种形式:type模仿class关键字造类 1.类名:class_name class_name = 'Foo' 2.类体代码:class_body #把类的属性和方法以字符串形式放入名称空间中 class_body = ''' count = 0 def run(self): print('run')''' class_dic = dict() exec(class_body,{},class_dic) #通过内置方法exec()从字符串变成类体代码 3.基类(父类) class_bases = (object,) 创建类成功 Foo = type(class_name,class_bases,class_dic) f = Foo() print(f.count) # 0
- 元类造类:控制造类的过程
#第二种方式:使用元类造类(控制制造类的过程),通过元类实例化成一个类,事实上还是借助了type #元类模板: class MyMeta(type): def __init__(self,class_name,class_dic,class_bases): **控制生成类的条件** if class_name.islower(): raise TypeError('类名必须大写') super().__init__(class_name,class_dic,class_bases) #通过metaclass创建类 class Foo(object,metaclass=MyMeta): count = 0 def run(self): print('run') f= Foo() print(f.count) # 0 f.run() # run
- 元类造类:控制对象产生的过程
#元类创建类时控制类的产生,也可以控制对象的产生 #元类》》元类实例化() = 类的过程:自动触发了__init__方法 #类实例化()》》=对象的过程:自动触发了__call__的方法 class MyMeta(type): #Foo=mymeta() def __init__(self,class_name,class_bases,class_dic): if class_name.islower(): raise TypeError('类名需要大写') # if not class_dic.get('__doc__'): # raise TypeError('需要加注释') super().__init__(class_name,class_bases,class_dic) ## f = Foo() = mymeta()() def __call__(self,*args,**kwargs): for i in args: if i.isdigit(): raise TypeError('error') obj = self.__new__(self) self.__init__(obj,*args,**kwargs) return obj class Foo(object,metaclass=MyMeta): def __init__(self,x): self.x = x x = input('请输入:') f = Foo(x) print(f.x)
小结:以元类早子类,子类的属性查找顺序:子类实例化对象本身,子类,父类,.....,object类,type元类,找不到即报错。