单列模式三种形式

一、元类补充
class Mymeta(type):
n=444
def __call__(self, *args, **kwargs):
obj = self.__new__(self) # self=Foo
# obj = object.__new__(self) # self=Foo
self.__init__(obj, *args, **kwargs)
return obj

class A(object):
n=333
# pass

class B(A):
n=222
# 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)) # object的类是type

obj=Foo(1,2)
# print(obj.__dict__)





二、练习:把自定义对象的属性变为隐藏属性
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):
#控制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): # Foo=Mymeta(...)
def __init__(self, name, age,sex):
self.name=name
self.age=age
self.sex=sex


obj=Foo('egon',18,'male')
print(obj.__dict__)




三、单列模式三种实现方式

1、什么是单例模式
单例模式:基于某种方法实例化多次得到的实例是同一个
2、为什么用单例模式
当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例
3、如何用

单例模式实 现方式一: 定义类方法

import settings

class Mysql:
__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(settings.IP,settings.PORT)
return cls.__instacne
# obj=Mysql('1.1.1.10',3306)

obj1=Mysql.from_conf()

obj2=Mysql.from_conf()
obj3=Mysql.from_conf()

print(obj1)
print(obj2)
print(obj3)

obj4=Mysql('10.10.10.11',3307)




单例模式实现方式二:实例化时候不传参
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() #wrapper()
obj2=Mysql() #wrapper()
obj3=Mysql() #wrapper()
print(obj1 is obj2 is obj3)
print(obj1)
print(obj2)
print(obj3)
obj4=Mysql('1.1.1.4',3308)
print(obj4)





单例模式实现方式三: 元类
import settings

class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic): #self=Mysql
super(Mymeta,self).__init__(class_name,class_bases,class_dic )
self.__instance=self.__new__(self) #造出一个Mysql的对象
self.__init__(self.__instance,settings.IP,settings.PORT) #从配置文件中加载配置完成Mysql对象的初始化

# obj=self.__new__(self)
# self.__init__(obj,settings.IP,settings.PORT)
# self.__instance=obj


def __call__(self, *args, **kwargs): #self=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=Mymeta(...)
def __init__(self,ip,port):
self.ip=ip
self.port=port


obj1=Mysql()
obj2=Mysql()
obj3=Mysql()
obj4=Mysql('10.10.10.11',3308)

print(obj1)
print(obj2)
print(obj3)
print(obj4)








posted @ 2018-07-05 17:11  Shinonon  阅读(395)  评论(0编辑  收藏  举报