首页 > 编程语言 > 详细

Python单例模式的实现

时间:2019-09-20 17:32:05      阅读:70      评论:0      收藏:0      [点我收藏+]
2.1、单例模式的概念
1、什么是单例
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在
 
2、单例的用途
当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
 
3、单例存在的原因
比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
 

2.2、单例模式的实现方法

2.2.1、使用模块
其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
MySingleton.py
class Singleton(object):
    def foo(self):
        print(foo...)
my_singleton = Singleton()

 

test.py
from MySingleton import my_singleton
 
print(id(my_singleton))  # 1079832199688
 
from MySingleton import my_singleton
 
print(id(my_singleton))  # 1079832199688

 

2.2.2、使用 __new__
为了使类只能出现一个实例,我们可以使用 __new__ 来控制实例的创建过程,代码如下:
class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance
 
class Person(Singleton):
    def __init__(self, name):
        self.name = name
 
if __name__ == __main__:
    p1 = Person(a)
    p2 = Person(b)
    print(id(p1), id(p2))  # 1007394335600 1007394335600
    print(p1 == p2)  # True
    print(p1 is p2)  # True

 

2.2.3、使用装饰器(decorator)
from functools import wraps
 
# Create your tests here.
def Singleton(cls):
    _instance = {}
    @wraps(cls)
    def wrap(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]
    return wrap
 
@Singleton
class Person():
    def __init__(self, name):
        self.name = name
 
if __name__ == __main__:
    p1 = Person(a)
    p2 = Person(b)
    print(id(p1), id(p2))  # 240896617272 240896617272
    print(p1 == p2)  # True
    print(p1 is p2)  # True
 
2.2.4、使用元类(metaclass)
元类(metaclass)可以控制类的创建过程,它主要做三件事:
1、 拦截类的创建。
2、 修改类的定义。
3、 返回修改后的类。
class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]
 
class Person(metaclass=Singleton):
    def __init__(self, name):
        self.name = name
 
if __name__ == __main__:
    p1 = Person(a)
    p2 = Person(b)
    print(id(p1), id(p2))  # 190305487616 190305487616
    print(p1 == p2)  # True
    print(p1 is p2)  # True
 
注意:
    Python2与Python3引用元类的方法不一样
# Python2
class MyClass(object):
    __metaclass__ = Singleton
 
# Python3
class MyClass(metaclass=Singleton):
   pass

 

文章来源:
 
 
 
 
 
 
 
 
 

Python单例模式的实现

原文:https://www.cnblogs.com/ygbh/p/11558449.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!