面向對象高級實戰之單例模式

1、什麼是單例模式

  • 單例模式:基於某種方法實例化屢次獲得實例是同一個

2、爲何用單例模式

  • 當實例化屢次獲得的對象中存放的屬性都同樣的狀況,應該將多個對象指向同一個內存,即同一個實例

115-單例模式-咱們都同樣.gif

3、單例模式(類內部定義靜態方法)

# settings.py
IP = '1.1.1.1'
PORT = 3306


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(IP, PORT)
        return cls.__instacne


obj1 = Mysql.from_conf()
obj2 = Mysql.from_conf()
obj3 = Mysql.from_conf()
print(obj1 is obj2 is obj3)
True
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('10.10.10.11', 3307)
print(obj4.__dict__)
{'ip': '10.10.10.11', 'port': 3307}

4、單例模式(裝飾器)

# settings.py
IP = '1.1.1.1'
PORT = 3306


def singleton(cls):
    cls.__instance = cls(IP, 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)
True
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('1.1.1.4', 3308)
print(obj4.__dict__)
{'ip': '1.1.1.4', 'port': 3308}

5、單例模式(元類)

# settings.py
IP = '1.1.1.1'
PORT = 3306


class Mymeta(type):
    def __init__(self, class_name, class_bases, class_dic):  # self = Mysql
        super(Mymeta, self).__init__(class_name, class_bases, class_dic)
        
        # 完成Mysql對象的初始化
        self.__instance = self.__new__(self)  # 造出一個Mysql的對象
        self.__init__(self.__instance, IP, 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()
<__main__.Mysql object at 0x10c7f1f98>
{'ip': '1.1.1.1', 'port': 3306}
print(obj1 is obj2 is obj3)
True
print(obj1.__dict__)
print(obj2.__dict__)
print(obj3.__dict__)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('10.10.10.11', 3308)

print(obj4.__dict__)
{'ip': '10.10.10.11', 'port': 3308}
print(Mysql.__dict__)
{'__module__': '__main__', '__init__': <function Mysql.__init__ at 0x10c6b1d90>, '__dict__': <attribute '__dict__' of 'Mysql' objects>, '__weakref__': <attribute '__weakref__' of 'Mysql' objects>, '__doc__': None, '_Mymeta__instance': <__main__.Mysql object at 0x10c7f1f98>}

115-單例模式-結束.jpg?x-oss-process=style/watermark

相關文章
相關標籤/搜索