python 学习笔记之单例模式

  • List item

单例模式

保证类只有一个实例对象,并且提供全局访问点,控制共享资源的冰箱访问

实现单例模式的方法:

构造函数私有化,创建一个静态方法来完成对象的初始化。

class Singleton(object):
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            #cls.instance = super(Singleton,cls).__new__(cls)
            # cls 参数代表着要实例化的类, new 方法必须要有返回值,返回实例化的对象
            cls.instance = super().__new__(cls)
        print("new")    
        return cls.instance
    def __init__(self):
        print("init") 
        # ps  __init__  和 new 方法的区别:
# new 是构造对象,分配内存空间,而 init 是对实例化出来的对象进行一些其他参数的初始化操作
s =  Singleton()
s1 =  Singleton()
print(s)
print(s1)
 python]$ python3 singleton.py 
new
init
new
init
<__main__.Singleton object at 0x7f7e5e6d9550>
<__main__.Singleton object at 0x7f7e5e6d9550>
单例模式的懒汉模式
## 单例的懒汉模式: 调用方法时才创建
class Singleton:
    __instance = None
    def __init__(self):
        if not Singleton.__instance:
            print("__init__method called ...")
        else:
            print("Instance already created", self.getInstance())
    @classmethod
    def getInstance(cls):
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__instance

s = Singleton()
print(s)
print("object created", Singleton.getInstance())
s1 = Singleton()  
print(s1)
s2 = Singleton() 
print(s2)  
console
python3 singleton.py 
__init__method called ...
<__main__.Singleton object at 0x7fb35bbbd438>
__init__method called ...
object created <__main__.Singleton object at 0x7fb35bbbfdd8>
Instance already created <__main__.Singleton object at 0x7fb35bbbfdd8>
<__main__.Singleton object at 0x7fb35bbbfe10>
Instance already created <__main__.Singleton object at 0x7fb35bbbfdd8>
<__main__.Singleton object at 0x7fb35bb494a8>
模块级别的单例模式
# singleton.py
class Singleton:
    def __init__(self, name, id):
        self.name = name
        self.id = id

singleton = Singleton("nini",1)
# a.py
from singleton import singleton
print("import a")
print(singleton)
print(" a: name: {} id: {}".format(singleton.name, singleton.id))
#b.py
from singleton import singleton
import a

print(singleton)
print(" b name: {} id: {}".format(singleton.name, singleton.id))
python]$ python3 b.py
import singleton
import a
<singleton.Singleton object at 0x7f45d3c996d8>
 a: name: nini id: 1
<singleton.Singleton object at 0x7f45d3c996d8>
 b: name: nini id: 1

在执行 python 命令时, 同一个模块只被导入一次。如果已经导入,则返回该模块的对象,如果没有导入,则导入该模块,并实例化。当同一个模块再次被导入时,它不会再次初始化,因为单例模式只能有一个对象

Monostate 单态模式
class Borg:
    __shared_state = {"1":"2"}
    def __init__(self):
        self.x =1
        self.__dict__ = self.__shared_state

b = Borg()
b1 = Borg()
b.x = 4
print("Borg Object 'b':", b)
print("Borg Object 'b1':", b1)
print("Borg Object state 'b'", b.__dict__)
print("Borg Object state 'b1'", b1.__dict__)
python3 singleton.py
Borg Object 'b': <__main__.Borg object at 0x7fdbaba004a8>
Borg Object 'b1': <__main__.Borg object at 0x7fdbaba004e0>
Borg Object state 'b' {'1': '2', 'x': 4}
Borg Object state 'b1' {'1': '2', 'x': 4}

b 和 b1 是两个对象,但是共享一个 dict

另外一只实现方式:

class Borg(object):
    __shared_state = {"1":"2"}
    def __new__(cls, *args, **kwargs):
        obj = super(Borg,cls).__new__(cls)
        obj.__dict__ = cls.__shared_state
        return obj
元类和单例模式
class Myint(type):
    def __call__(cls, *args, **kwargs):
        print("***** Here is my int ****",args)
        print("Now do whatever you want with these objects...")
        return type.__call__ (cls, *args, **kwargs)
class int(metaclass=Myint):
    def __init__(self, x,y):
        self.x =x
        self.y =y

## 如果一个类实现了 __call__ 方法那么就可以像调用函数一样调用他
i = int(5,6)
# 元类控制着对象的实例化,元类对类创建和对象实例化有着更多的控制权,所以可以用元类实现单例模式
python3 singleton.py
***** Here is my int **** (5, 6)
Now do whatever you want with these objects...

使用元类实现单例模式:


class MetaSingle(type):
    __instance = {}
    def __call__(cls, *args, **kargs):
        if cls not in cls.__instance:
            cls.__instance[cls] = super(MetaSingle, cls).__call__(*args, **kargs)
        return cls.__instance[cls]
class Logger(metaclass = MetaSingle):
    pass

logger1 = Logger()
logger2 = Logger()
print(logger1, logger2)
python3 singleton.py
<__main__.Logger object at 0x7fd4dec5a4e0> <__main__.Logger object at 0x7fd4dec5a4e0>
单例模式的实际例子
# example: 为基础设置提供运行状况的监控服务,我们将 HealthCheck 类作为单例实现,我们还要维护一个被监控的服务器列表
class HealthyCheck:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if not HealthyCheck.__instance:
            cls.__instance = super(HealthyCheck,cls).__new__(cls, *args, **kwargs)
            print('create heathycheck instance')
        return HealthyCheck.__instance
    def __init__(self):
        self._servers = []
        print("init  healthy check")

    def addServer(self):
        self._servers.append("server1")
        self._servers.append("server2")
        self._servers.append("server3")
        self._servers.append("server4")
    def changeServer(self):
        self._servers.pop()
        self._servers.append("server5")

hc1 = HealthyCheck()
hc2 = HealthyCheck()
print(hc1,hc2)
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]) 
单例模式的缺点

全局变量可能在某处被误改,而开发人员认为他没有改变,还在应用程序的其他地方使用他
由于单例模式只创建一个对象,在这种情况下会对同一个对象创建多个引用
依赖全局变量的类,会和其他类紧密耦合。可能在无意中改变其他的类

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值