08-3 面向对象高级
目录
1 面向对象高级
1.1 isinstance,issubclass
isinstance判断是否为类的实例化对象,会检测父类,而type不会检测父类
lis = [1,2,3]
print(isinstance(lis,list))
# True
issubclass,判断是否为其子类
class Person:
def __init__(self,name):
self.name = name
class Student(Person):
def sing(self):
print('i am singing!')
print(issubclass(Student,Person))
1.2 反射
通过字符串来操作对象的属性和方法。
- hasattr:通过字符串判断是否类属性存在
- getattr:通过字符串获取类属性
- setattr:通过字符串修改类属性
- delattr:通过字符串删除类属性
1.3 call
实例化一个对象调用__init__方法,对象再加括号就会调用__call__方法。元类中通过call方法来控制对象的生成。
class Foo:
def __init__(self):
print('Foo()会触发我')
def __call__(self):
print('Foo()()/f()会触发我')
f = Foo()
f()
1.4 new
在init之前执行,会创建一个空对象
class Foo:
def __new__(self):
print('new')
obj = object.__new__(self)
return obj
def __init__(self):
print('init')
f = Foo()
1.5 元类
类也是对象。
元类用来造类的。
默认所有的类的元类都是type。我们可以继承type实现自己的元类,目的是为了控制类的创建过程。
元类()-->类-->init
元类()()-->对象--->call
类分为几部分:类名/类体名称空间/父类们
__call__ 调用类实例化对象时 自动执行
__init__ 创建类对象的时候执行
__new__ 创建对象时 会调用__new__来获得一个空对象 然后调用类中的__init__方法进行初始化
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic):
# 控制类的逻辑代码
super().__init__(class_name,class_bases,class_dic)
def __call__(self,*args,**kwargs):
# 控制类实例化的参数
obj = self.__new__(self) # obj就是实例化的对象
self.__init__(obj,*args,**kwargs)
print(obj.__dict__)
# 控制类实例化的逻辑
return obj
class People(metaclass=Mymeta): # meclass=Mymeta(people=Mymeta()) 接收类名/内替代码/基类传给Mymeta,(之前可以进行限制)进而传给type
def __init__(self,name,age):
self.name = name
self.age = age
1.6 单例模式
一个类只能产生一个对象,目的是为了减少资源开销。
当这个类的对象中的数据是共享的时候,我们可以使用单例模式。
有3种实现方式。
1.6.1 利用类的绑定方法的特性
NAME = 'nick'
AGE = 18
class People():
__instance = None
@classmethod
def from_conf(cls):
if cls.__instance:
return cls.__instance
cls.__instance = cls(NAME,AGE)
return cls.__instance
1.6.2 利用装饰器
NAME = 'nick'
AGE = 18
def deco(cls):
cls.__instance = cls(NAME,AGE)
def wrapper(*args,**kwargs):
if len(args) == 0 and len(kwargs) == 0:
return cls.__instance
res = cls(*args,**kwargs)
return res
return wrapper
@deco
class People():
def __init__(self,name,age):
self.name = name
self.age = age
peo1 = People()
peo2 = People()
1.6.3 利用元类(正宗的)
NAME = 'nick'
AGE = 18
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dict):
super().__init__(class_name,class_bases,class_dict)
self.__instance = self(NAME,AGE)
def __call__(self,*args,**kwargs):
if len(args) == 0 and len(kwargs) == 0:
return self.__instance
obj = object.__new__(self)
self.__init__(obj,*args,**kwargs)
return obj
class People(metaclass=Mymeta):
def __init__(self,name,age):
self.name = name
self.age = age
peo1 = People()
peo2 = People()