python的单例模式

# 一、元类补充:
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)

猜你喜欢

转载自blog.csdn.net/qq_35540539/article/details/80887369