python中实现单例模式以及网上的一些错误

单例模式

简介:

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

例如:服务器程序的配置信息存放在一个文件中,客户端通过一个 Config 的类来读取配置文件的信息。当有很多地方都需要使用配置文件的内容时就需要创建 创建多个Config 对象的实例,从而浪费内存资源,尤其是在配置文件内容很多的情况下。

列举几种实现单例的方法:
1、使用import调用模块:

Python 的模块就是天然的单例模式,当模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,不再次执行模块代码。所以将相关的函数和数据定义在一个模块中,可以获得一个单例对象。

比如:创建一个py文件sing,写一个SingOK类,在类里创建一个func方法,并实例化一个singleton对象(必须,因为如果你再另一个模块调用的是SingOK这个类然后再实例化对象,就不是单例模式了),在另一个py文件中调用如下:

from SingOK import  singleton
singleton.func()

# 查看是否是单例, 两个变量指向同一个地址
a = singleton
b = singleton
print(id(a))
print(id(b))
2.使用装饰器:

通过装饰器,将创建的类在实例化的时候只使用同一个类第一次实例化的结果。之后相同的类只取字典instances中的实例。

from functools import wraps
def singleton(cls):
    instances = {}
    @wraps(cls)
    def _singleton(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return _singleton

注意:网上有下面这种写法,是由于对于装饰器理解不透彻导致,这样做是可以使用同一个实例。但是对于传参的类,实例化的时候会报错的。原因是内部的函数_singleton并没有形参,应该将singleton的形参放到_singleton来。

from functools import wraps
def singleton(cls, *args, **kwargs):
    instances = {}
    @wraps(cls)
    def _singleton():
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return _singleton

测试上面的注意事项的代码:

@singleton
class sg:

    def __init__(self, id):
        self.id = id

    def name(self):
        print('name')

a = sg('23')
b = sg('45')
a.name()
print(id(a))
print(id(b))
3.使用__new__()方法

python类中的__new__()方法是真正创建一个实例的方法,每创建一个实例的时候都会先调用它去new一个实例对象。重写类中的__new__()方法使之成为单例。

class Tools(object):
    instance = None

    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super(Tools, cls).__new__(cls)
        return cls.instance

或者:

class Tools(object):

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Tools, cls).__new__(cls)
        return cls.instance
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙子园

期待你的鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值