面试必备-单例模式5种实现方法

一,私有属性判断法

class Single:
    _obj = None
    _init_flag = True

    def __new__(cls, *args, **kwargs):
        if cls._obj == None:
            cls._obj = super().__new__(cls)

        return cls._obj

    def __init__(self,name):
        if Single._init_flag:
            self.name = name
            print('11111')
            Single._init_flag = False

二,类方法

# 类方法,调用绑定给类的方法产生对象
class Single2:

    _obj = None
    def __init__(self,name,age):
        print('222222222')
        self.name = name
        self.age = age

    @classmethod
    def singleton(cls,*args,**kwargs):
        if not cls._obj :
            cls._obj = cls(*args,**kwargs)
        return cls._obj

三,装饰器法

# 装饰器方法
def single_wrapper(cls):
    _instance = {}

    def inner(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, *kwargs)

        return _instance[cls]
    return inner

@single_wrapper
class Single3:
    def __init__(self, name, age):
        print('3333333333')
        self.name = name
        self.age = age

四,元类法

# 元类方法,传入相同参数返回同一个对象,不同参数返回不同对象
class MyMeta(type):


    # 1、先触发元类里面的__init__
    def __init__(self, name, base, attrs):  # self --> Goo
        # *** 造空的对象, 然后赋值给了Goo类中的_instance类属性
        self._instance = object.__new__(self)
        self._argument = []
        self._obj = {}

        # 将类名、基类、类的名称空间,传给type里面的__init__
        super().__init__(name, base, attrs)
        # type.__init__(self, name, base, attrs)

    # 2、当调用Goo类时,等同于调用了由元类实例化的到的对象
    def __call__(self, *args, **kwargs):

        # 判断调用Goo时是否传参
        if args or kwargs:
            list = [args,kwargs]

            if list in self._argument:
                position = self._argument.index([args, kwargs])
                obj = self._obj[position]
                return obj
            else:

                obj = object.__new__(self)
                self.__init__(obj, *args, **kwargs)

                self._argument.append([args,kwargs])
                position = self._argument.index([args,kwargs])
                self._obj[position]=obj
                return obj

        else:
            return object.__new__(self)
        
class Goo(metaclass=MyMeta):  # Goo = MyMeta(Goo)

    def __init__(self, ip,port):
        self.ip=ip
        self.pot=port

五,导入模块法

# 导入模块法
test.py

class Single4:
    pass

instance = Single4()


from scripts.test import instance

g = instance
h = instance
print(g == h)
posted @ 2020-07-25 16:40  Franciszw  阅读(185)  评论(0编辑  收藏  举报