# 一、元类补充: class Mymeta(type): n=444 def __call__(self, *args, **kwargs):#self=Foo obj=self.__new__(self) #创建一个空对象 self.__init__(obj,*args,**kwargs) return obj class A(object): # n=33 pass class B(A): # n=22 pass class Foo(B,metaclass=Mymeta): #Foo=Mymeta(....) # n=111 def __init__(self,x,y): self.x=x self.y=y print(Foo.n) #查找顺序 # 1、先对象层:Foo->B->A->object # 2.然后元类层:Mymeta->type print(type(object))#为元类type obj=Foo(1,2)
print(obj.__dict__)
# 二。自定义元类控制类的对象的产生过程 # 1.控制对象的属性隐藏 class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): #控制Foo的创建 super().__init__(class_name,class_bases,class_dic) def __call__(self, *args, **kwargs): #控制Foo的调用过程,即Foo对象的产生过程 obj=self.__new__(self) self.__init__(obj,*args,**kwargs) obj.__dict__={'_%s__%s'%(self.__name__,k):v for k,v in obj.__dict__.items()} return obj class Foo(object,metaclass=Mymeta): def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def get_info(self): print(self.__name) obj=Foo('egon',18,'male') print(obj.__dict__) obj.get_info() #变更对象的属性隐藏
''' 1.什么是单例模式 单例模式:基于某种实例化多次得到实例是同一个 2.为何用单例模式 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存, 即用同一个实例 3,如何用 ''' # 单例模式实现方式一: import settings class Mysql: __instance=None def __init__(self,ip,port): self.ip=ip self.port=port @classmethod def from_conf(cls): if cls.__instance is None:#如果不为空则实例化过 cls.__instance=cls(settings.IP,settings.PORT)#产生对象并赋值 return cls.__instance obj=Mysql('1.2.3.4',338) obj1=Mysql.from_conf() obj2=Mysql.from_conf() obj3=Mysql.from_conf() print(obj1) print(obj2) print(obj3)#三个调用类中函数功能得到的实例一样,即指向同一内存地址 print(obj)#正常实例化对比 # 单例模式实现方式二: import settings def singleton(cls): cls.__instance=cls(settings.IP,settings.PORT) def wrapper(*args,**kwargs): if len(args)==0 and len(kwargs)==0: return cls.__instance return cls(*args,**kwargs) return wrapper @singleton #Mysql=singleton(mysql)#Mysql=wrapper class Mysql: def __init__(self,ip,port): self.ip=ip self.port=port obj1=Mysql() obj2=Mysql() obj3=Mysql()#wrapper() print(obj1 is obj2 is obj3) obj=Mysql('1111,222',3308) print(obj) # 单例模式实现方式三: import settings class Mymeta(type): def __init__(self,class_name,class_bases,class_dic):#self=Mysql super().__init__(class_name,class_bases,class_dic) self.__instance=self.__new__(self)#造出一个Mysql的对象 self.__init__(self.__instance,settings.IP,settings.PORT) def __call__(self, *args, **kwargs): if len(args)==0 and len(kwargs): return self.__instance obj=self.__new__(self) self.__init__(obj,*args,**kwargs) return obj class Mysql(object,metaclass=Mymeta): def __init__(self,ip,port): self.ip=ip self.port=port obj1=Mysql() obj2=Mysql() obj3=Mysql() obj4=Mysql('10,24,4,4',3303) print(obj1) print(obj2) print(obj3) print(obj4)