python之元类高级应用,自定义元类隐藏属性,三种单例模式
1.自定义元类隐藏对象属性
class Mmeta(type):
def __init__(self,class_name,class_bases,class_dic):
super(Mymeta,self).__init__(self,class_name,class_bases,class_dic)
def __call__(self,*args,**kwargs):
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)
self.name=name
self.age
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dic):
# 控制Foo的创建 即类的创建 初始化
super(Mymeta, self).__init__(class_name, class_bases, class_dic)
def __call__(self, *args, **kwargs): # 调用对象的自动触发 self=foo 把foo当做对象 python中一切皆对象
# 控制Foo的调用过程,即Foo对象的产生过程
obj = self.__new__(self) # self=foo #新建一个空对象obj
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): # Foo=Mymeta(......) 把foo当做一个对象来看待
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
obj = Foo('egon', 18, 'mele')
print(obj.__dict__)
# 把所有的继承类看做对象,先找对象,object是所有对象的父类 object看做对象的话 type是object元类 最终找的是type
# 在找自定义类-type type是所有对象和类的元类
单例模式:基于某种方式实例化多次,得到实例是同一个
为啥要用:
当实例化多次得到的对象中存放的属性都一样时,应该将多个对象指向同一个内存地址,即同一个实例。
1.类中定义
import setting
class Mymeta:
__instacne=None
def __init__(self,ip,port)
self.ip=ip
self.port=port
@classmethod
def form-conf(cls):
if cls.__instacne is None:
cls.__instacne=cls(setting_ip,setting_port)
return cls.__instacne
import setting
"""
# 1.在类中定义单例模式方法一:
class Mymeta:
__instacne = None
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod
def from_conf(cls): # 类调用读取文件实例化,多次读取相同内容但内存地址不一样#节省内存
if cls.__instacne is None: # 判断是否有没有实例化赋值
cls.__instacne = cls(setting.IP, setting.port)
return cls.__instacne
"""
2.装饰器定义法
def singleton(cls):
__instance=cls(setting_ip,setting_port)
def wrapper (*args,**kwargs):
if len(args)==0 and len(kwargs)==0:
return __instance
return cls(*args,**kwargs)
return wrapper
@singleton
class Mymeta
def __init__(self,ip,port)
self.ip=ip
self.port=port
# 装饰器的单例模式方式二
"""
import setting
def singleton(cls): #cls是原始的mysql内存地址
__instacne = cls(setting.IP, setting.port) #直接先导入文件实例化
def wrapper(*args, **kwargs): #wrapper=mysql赋值过后内存地址
if len(*args) == 0 and len(**kwargs) == 0:#在判断是否用户输入参数
return __instacne #没有是直接返回上面已经实例化的
return cls(*args, **kwargs) #用户输入的有参数的话直接实例化一个兵返回
return wrapper
@singleton
class Mysql: #Mysql=singleton(Mysql) mysql内存地址给cls # singleton(Mysql)= wrapper内存地址 调用mysql是调用warpper
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj = Mysql()
obj2 = Mysql()
obj3 = Mysql()
"""
3.元类定义法
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic)
super(Mymeta,self).__init__(class_name,class_bases,class_dic)
self.__instance=self.__new__(self)
seif.__init__(self,__instance,setting_ip,setting_port)
def __call__(self,*args,**kwargs):
if len(args)==0 and len(kwargs)==0:
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
# 单例模式方式三
import setting
class Mymeta(type):
def __init__(self, class_name, class_beses, class_dic): # 一开始就初始化
super(Mymeta, self).__init__(class_name, class_beses, class_dic)
self.__instance = self.__new__(self) # 造出一个Mysql空对象
self.__init__(self.__instance, setting.IP, setting.port) #在配置文件中加载配置完成Mysql对象初始化
#print(self.__instance)
# print(self.__instance.__dict__)
def __call__(self, *args, **kwargs): # self=Mysql #接受用户传值 调用对象自动触发 把Mysql看做对象
if len(args) == 0 and len(kwargs) == 0: # 判断有没有传值
return self.__instance
obj = self.__new__(self) # 造出一个空对象
self.__init__(obj, *args, **kwargs) # 根据传值参数,初始化对象
return obj
class Mysql(object, metaclass=Mymeta): # 把Mysql当做一个对象看待 #Mysql=Mymeta(...)调用元类生成mysql对象
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj = Mysql()
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql('10.10.10.10', 3308)
print(obj)
print(obj1)
print(obj2)
print(obj3)
Mysql看做对象
if len(args) == 0 and len(kwargs) == 0: # 判断有没有传值
return self.__instance
obj = self.__new__(self) # 造出一个空对象
self.__init__(obj, *args, **kwargs) # 根据传值参数,初始化对象
return obj
class Mysql(object, metaclass=Mymeta): # 把Mysql当做一个对象看待 #Mysql=Mymeta(...)调用元类生成mysql对象
def __init__(self, ip, port):
self.ip = ip
self.port = port
obj = Mysql()
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql('10.10.10.10', 3308)
print(obj)
print(obj1)
print(obj2)
print(obj3)