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

举报
橙子园 发表于 2022/05/26 00:12:34 2022/05/26
【摘要】 单例模式 简介: 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。 例如:服务器程序的配置信息存放在一个文件中,客户端通过一个...

单例模式

简介:

单例模式(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))

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

注意:网上有下面这种写法,是由于对于装饰器理解不透彻导致,这样做是可以使用同一个实例。但是对于传参的类,实例化的时候会报错的。原因是内部的函数_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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

@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))

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

或者:

class Tools(object):

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Tools, cls).__new__(cls)
        return cls.instance

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

文章来源: blog.csdn.net,作者:橙子园,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/Chenftli/article/details/101367177

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。