元类、单例模式的四种实现方式

元类

class Mymete(type):
    n=444
    def __call__(self,*args,**kwargs):
        obj=self.__new__(self)
        self.__init__(obj,*args,**kwargs)
        return obj

class A(object):
    n=333

class B(A):
    n=222

class Foo(B,metaclass=Mymeta):
    n=111
    def __init__(self,x,y):
        self,x=x
        self,y=y

print(Foo.n)

print(type(object))

obj=Foo()

print(obj.__dict__)

查找顺序:
1.先对象层:Foo->B->A->object

2.然后元类层:Mymeta->type

 

单例模式

1.什么是单例模式

    单例模式:基于某种方法实例化多次得到实例是同一个

2.为何用单例模式

    当实例化多次得到的对象中存在的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例

3.如何使用:

单例模式实现方式一:(在类中通过定义classmethod来进行调用)

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

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)
print(obj4)

单例模式实现方式二:(定义一个装饰器实现单例模式)

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对象的初始化

        # print(self.__instance)
        # print(self.__instance.__dict__)

    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)

ps:

super() 函数是用于调用父类(超类)的一个方法。

super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。

单例模式实现方式四:(通过导入模块实现)

# 作为Python模块时是天然的单例模式

# 创建一个sington.py文件,内容如下:
class Singleton(object):
    def foo(self):
        pass
mysington = Singleton()

# 运用
from sington import mysington
mysington.foo()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值