-->

08-3 面向对象高级

2020-11-30 00:53发布

目录
  • 1 面向对象高级
    • 1.1 isinstance,issubclass
    • 1.2 反射
    • 1.3 call
    • 1.4 new
    • 1.5 元类
    • 1.6 单例模式
      • 1.6.1 利用类的绑定方法的特性
      • 1.6.2 利用装饰器
      • 1.6.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 反射

通过字符串来操作对象的属性和方法。

  1. hasattr:通过字符串判断是否类属性存在
  2. getattr:通过字符串获取类属性
  3. setattr:通过字符串修改类属性
  4. 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()

标签: