单例设计模式

理解单例设计模式
只允许Singleton类生成一个实例。
如果已经有一个实例了,我们会重复提供同一个对象

class Singleton(object):

    def __new__(self):
        if not hasattr(self, 'instance'):
            self.instance = super(Singleton, self).__new__(self)
        return self.instance

s = Singleton()
print("Object created ", s)

s1 = Singleton()
print("Object created ", s1)

002_1

懒汉式实例化
例如在导入模块的时候,我们可能会无意中创建一个对象,但当时根本用不到它。
懒汉式实例化能够确保在实际需要时寻创建对象。
所以,懒汉式实例化是一种节约资源并仅在需要时才创建它们的方式。

class Singleton(object):

    __instance = None

    def __init__(self):
        if not Singleton.__instance:
            print("__init__method called..")
        else:
            print("Instance already created: ", self.getInstance())

    @classmethod
    def getInstance(self):
        if not self.__instance:
            self.__instance = Singleton()
        return self.__instance

s = Singleton() # 类已初始化,但未创建对象
print("Object created ", Singleton.getInstance()) # 在这里创建

s1 = Singleton() # 实例已创建

002_2

Monostate单(态)例模式(1)

class Borg(object):
    __shared_state = {"1":"2"}
    def __init__(self):
        self.x = 1
        self.__dict__ = self.__shared_state
        pass

b = Borg()
b1 = Borg()
b.x = 4

print("Borg Object 'b': ", b) ## b和b1是不同的对象
print("Borg Object 'b1': ", b1)
print("Object State 'b': ", b.__dict__) ## b和b1处于相同状态
print("Object State 'b1': ", b1.__dict__)

002_3

Monostate单(态)例模式(2)

class Borg(object):
    _shared_state = {"1":"2"}
    def __new__(self, *args, **kwargs):
        obj = super(Borg, self).__new__(self, *args, **kwargs)
        obj.__dict__ = self._shared_state
        return obj

b = Borg()
b1 = Borg()

print("Borg Object 'b': ", b) ## b和b1是不同的对象
print("Borg Object 'b1': ", b1)
print("Object State 'b': ", b.__dict__) ## b和b1处于相同状态
print("Object State 'b1': ", b1.__dict__)

002_4

单例和元类(1)

class MyInt(type):
    def __call__(self, *args, **kwds):
        print("***** Here's My int *****", args)
        print("Now do whatever you want with these objects...")
        return type.__call__(self, *args, **kwds)

class int(metaclass=MyInt):
    def __init__(self, x, y):
        self.x = x
        self.y = y

i = int(4, 5)

002_5

单例和元类(2)

class MetaSingleton(type):
    _instances = {}
    def __call__(self, *args, **kwargs):
        if self not in self._instances:
            self._instances[self] = super(MetaSingleton, self).__call__(*args, **kwargs)
        return self._instances[self]

class Logger(metaclass=MetaSingleton):
    pass

logger1 = Logger()
logger2 = Logger()
print(logger1)
print(logger2)

002_6

单例模式 I

import sqlite3

class MetaSingleton(type):
    _instances = {}
    def __call__(self, *args, **kwargs):
        if self not in self._instances:
            self._instances[self] = super(MetaSingleton, self).__call__(*args, **kwargs)
        return self._instances[self]

class Database(metaclass=MetaSingleton):
    connection = None

    def connect(self):
        if self.connection is None:
            self.connection = sqlite3.connect("db.sqlite3")
            self.cursorobj = self.connection.cursor()
        return self.cursorobj

db1 = Database().connect()
db2 = Database().connect()

print("Database Objects DB1", db1)
print("Database Objects DB2", db2)

002_7

单例模式 II

class HealthCheck(object):
    _instance = None
    def __new__(self, *args, **kwargs):
        if not HealthCheck._instance:
            HealthCheck._instance = super(HealthCheck, self).__new__(self, *args, **kwargs)
        return HealthCheck._instance

    def __init__(self):
        self._servers = []

    def addServer(self):
        self._servers.append("Server 1")
        self._servers.append("Server 2")
        self._servers.append("Server 3")
        self._servers.append("Server 4")

    def changeServer(self):
        self._servers.pop()
        self._servers.append("Server 5")

hc1 = HealthCheck()
hc2 = HealthCheck()

hc1.addServer()
print("Schedule health check for servers (1)..")
for i in range(4):
    print("Checking ", hc1._servers[i])

hc2.changeServer()
print("Schedule health check for servers (2)..")
for i in range(4):
    print("Checking ", hc2._servers[i])

002_8