精华内容
下载资源
问答
  • 语言是共通的,想要用不同语言实现单例模式,首先要清楚什么是单例模式,单例模式即一个类有且仅有一个实例,那么通过python怎么实现一个类只能有一个实例呢。首先先创建一个类,比如宇宙只有一个地球class Earth:...

    语言是共通的,想要用不同语言实现单例模式,首先要清楚什么是单例模式,单例模式即一个类有且仅有一个实例,那么通过python怎么实现一个类只能有一个实例呢。

    首先先创建一个类,比如宇宙只有一个地球

    class Earth:

    pass

    a = Earth()

    print(id(a))

    b = Earth()

    print(id(b))

    运行结果如下:

    通过打印实例的id可以发现,地球类默认创建了两个实例。

    那么怎么能够让类只创建一个实例,而后再创建的实例是返回上一次的对象的引用呢?

    我们了解到,python中,一个类创建对象实例是通过调用父类object的 __new__(cls)方法来创建对象的

    我们可以通过重写 __new__(cls)方法去实现类只创建一个实例

    代码如下:

    class Earth(object):

    __instance=None #定义一个类属性做判断

    def __new__(cls):

    if cls.__instance==None:

    #如果__instance为空证明是第一次创建实例

    #通过父类的__new__(cls)创建实例

    cls.__instance==object.__new__(cls)

    return cls.__instance

    else:

    #返回上一个对象的引用

    return cls.__instance

    a = Earth()

    print(id(a))

    b = Earth()

    print(id(b))

    运行结果如下:

    可以看出它们id相同,是同一个对象。

    ---------------------

    作者:筒芋的甜味

    来源:CSDN

    原文:https://blog.csdn.net/ctyct_/article/details/79677125

    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • 小猿圈alex讲了实现单例模式的好几种方法,小编把最经典,也是最经常用的两种实现单例模式的方法呈现给大家,如果想学其他的单例,可以去小猿圈看一下alex的课程,学习一下。 单例顾名思义就是这个类只能创建一个...

    小猿圈alex讲了实现单例模式的好几种方法,小编把最经典,也是最经常用的两种实现单例模式的方法呈现给大家,如果想学其他的单例,可以去小猿圈看一下alex的课程,学习一下。

    单例顾名思义就是这个类只能创建一个实例,那怎么创建呢?

    1、__new__实现单例:

      class Foo(object):
    
      def __init__(self,name):
    
        self.name=name
    
      def __new__(cls,*args,**kwargs):
    
        if not hasattr(cls,instance): #对象不存在instance属性
    
          cls.instance=super().__new__(cls,*args,**kwargs)
    
        return cls.instance #创建了一个实例,还没初始化对象
    
    f=Foo('hello')
    
    f1=Foo('hi')
    
    f.name=hello f1.name=hi
    
    id(f)==id(f1)

    地址没变 属性变了

    2、使用装饰器实现的单例:   

     class Demo(cls,*ags,**kwargs):
    
      instance={}
    
      def foo(*args,**kwargs):
    
        if cls not in instance:
    
          instance[cls]=cls(*args,**kwargs)#具体的实例(已经初始化好的实例对象)
    
        return instance[cls]
    
        return foo
    
    @Demo
    
    class School(object):
    
      def __init__(self,name)
    
      self.name=name
    
    s=School('hafo')
    
    s1=School('qinghua')
    
    s.name=hafo s1.name=hafo s1==s

    地址没变,属性也没变

    朋友们看出两者实现单例的异同点了吗?虽然两者都可以实现单例,但是__new__实现的单例,虽然只能实现一个实例但是属性改变了,装饰器实现的单例,可以保证id和属性都保持一个,如果朋友们对其他的单例之间不同感兴趣,可以去小猿圈看一下alex讲的单例实现的内容。

    展开全文
  • Python实现单例模式

    万次阅读 多人点赞 2018-03-24 14:52:25
    语言是共通的,想要用不同语言实现单例模式,首先要清楚什么是单例模式,单例模式即一个类有且仅有一个实例,那么通过python怎么实现一个类只能有一个实例呢。 首先先创建一个类,比如宇宙只有一个地球 class ...

    语言是共通的,想要用不同语言实现单例模式,首先要清楚什么是单例模式,单例模式即一个类有且仅有一个实例,那么通过python怎么实现一个类只能有一个实例呢。

    首先先创建一个类,比如宇宙只有一个地球

    class Earth:
        pass
    
    a = Earth()
    print(id(a))
    b = Earth()
    print(id(b))

    运行结果如下:

    通过打印实例的id可以发现,地球类默认创建了两个实例。

    那么怎么能够让类只创建一个实例,而后再创建的实例是返回上一次的对象的引用呢?

    我们了解到,python中,一个类创建对象实例是通过调用父类object的 __new__(cls)方法来创建对象的

    我们可以通过重写 __new__(cls)方法去实现类只创建一个实例

    代码如下:

    class Earth(object):
        __instance=None #定义一个类属性做判断
    
        def __new__(cls):
    
            if cls.__instance==None:
                #如果__instance为空证明是第一次创建实例
                #通过父类的__new__(cls)创建实例
                cls.__instance=object.__new__(cls)
                return  cls.__instance
            else:
                #返回上一个对象的引用
                return cls.__instance
    
    a = Earth()
    print(id(a))
    b = Earth()
    print(id(b))

    运行结果如下:

    可以看出它们id相同,是同一个对象。

    展开全文
  • 本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python实现,每个设计模式都是围绕如下三个问题:为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的问题?是...

    本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题:

    为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的问题?

    是什么?通过Python语言来去实现这个设计模式,用于解决为什么中提到的问题。

    怎么用?理解了为什么我们也就基本了解了什么情况下使用这个模式,不过在这里还是会细化使用场景,阐述模式的局限和优缺点。

    这一篇我们先来看看单例模式。单例模式是设计模式中逻辑最简单,最容易理解的一个模式,简单到只需要一句话就可以理解,即"保证只有一个对象实例的模式”。问题的关键在于实现起来并没有想象的那么简单。不过我们还是先来讨论下为什么需要这个模式吧。

    为什么

    我们首先来看看单例模式的使用场景,然后再来分析为什么需要单例模式。

    Python的logger就是一个单例模式,用以日志记录

    Windows的资源管理器是一个单例模式

    线程池,数据库连接池等资源池一般也用单例模式

    网站计数器

    从这些使用场景我们可以总结下什么情况下需要单例模式:

    当每个实例都会占用资源,而且实例初始化会影响性能,这个时候就可以考虑使用单例模式,它给我们带来的好处是只有一个实例占用资源,并且只需初始化一次;

    当有同步需要的时候,可以通过一个实例来进行同步控制,比如对某个共享文件(如日志文件)的控制,对计数器的同步控制等,这种情况下由于只有一个实例,所以不用担心同步问题。

    当然所有使用单例模式的前提是我们的确用一个实例就可以搞定要解决的问题,而不需要多个实例,如果每个实例都需要维护自己的状态,这种情况下单例模式肯定是不适用的。

    接下来看看如何使用Python来实现一个单例模式。

    是什么

    最开始的想法很简单,实现如下:

    classSingleton(object):__instance =Nonedef __new__(cls, *args, **kwargs): #这里不能使用__init__,因为__init__是在instance已经生成以后才去调用的

    if cls.__instance isNone:

    cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs)return cls.__instances1=Singleton()

    s2=Singleton()prints1print s2

    打印结果如下:

    <__main__.Singleton object at 0x7f3580dbe110>

    <__main__.Singleton object at 0x7f3580dbe110>

    可以看出两次创建对象,结果返回的是同一个对象实例,我们再让我们的例子更接近真实的使用场景来看看

    classSingleton(object):__instance =Nonedef __new__(cls, *args, **kwargs):if cls.__instance isNone:

    cls.__instance =super(

    Singleton, cls).__new__(cls, *args, **kwargs)return cls.__instance

    def __init__(self, status_number):

    self.status_number=status_number

    s1= Singleton(2)

    s2= Singleton(5)prints1prints2prints1.status_numberprint s2.status_number

    这里我们使用了_init_方法,下面是打印结果,可以看出确实是只有一个实例,共享了实例的变量

    <__main__.Singleton object at 0x7f5116865490>

    <__main__.Singleton object at 0x7f5116865490>

    5

    5

    不过这个例子中有一个问题我们没有解决,那就是多线程的问题,当有多个线程同时去初始化对象时,就很可能同时判断__instance is None,从而进入初始化instance的代码中。所以为了解决这个问题,我们必须通过同步锁来解决这个问题。以下例子来自xiaorui

    importthreadingtry:from synchronize importmake_synchronizedexceptImportError:defmake_synchronized(func):importthreading

    func.__lock__ =threading.Lock()def synced_func(*args, **kws):

    with func.__lock__:return func(*args, **kws)returnsynced_funcclassSingleton(object):

    instance=None

    @make_synchronizeddef __new__(cls, *args, **kwargs):if cls.instance isNone:

    cls.instance= object.__new__(cls, *args, **kwargs)returncls.instancedef __init__(self):

    self.blog= "xiaorui.cc"

    defgo(self):pass

    defworker():

    e=Singleton()printid(e)

    e.go()deftest():

    e1=Singleton()

    e2=Singleton()

    e1.blog= 123

    printe1.blogprinte2.blogprintid(e1)printid(e2)if __name__ == "__main__":

    test()

    task=[]for one in range(30):

    t= threading.Thread(target=worker)

    task.append(t)for one intask:

    one.start()for one intask:

    one.join()

    至此我们的单例模式实现代码已经接近完美了,不过我们是否可以更简单地使用单例模式呢?答案是有的,接下来就看看如何更简单地使用单例模式。

    怎么用

    在Python的官方网站给了两个例子是用装饰符来修饰类,从而使得类变成了单例模式,使得我们可以通过更加简单的方式去实现单例模式

    例子:(这里只给出一个例子,因为更简单,另外一个大家可以看官网Singleton

    defsingleton(cls):

    instance=cls()

    instance.__call__ = lambda: instancereturninstance#

    #Sample use#@singletonclassHighlander:

    x= 100

    #Of course you can have any attributes or methods you like.

    Highlander()is Highlander() is Highlander #=> True

    id(Highlander()) == id(Highlander) #=> True

    Highlander().x == Highlander.x == 100 #=> True

    Highlander.x = 50Highlander().x== Highlander.x == 50 #=> True

    这里简单解释下:

    在定义class Highlander的时候已经执行完所有singleton装饰器中的代码,得到了一个instance,所以这之后所有对Highlander的调用实际上是在调用instance的_call_ 方法。

    我们通过lambda函数定义了_call_方法让它始终返回instance,因此Highlander()和Highlander都返回instance

    同时由于在类定义代码执行时就已经创建了instance,所以后续不论是多线程还是单线程,在调用Highlander时都是在调用instance的_call_方法,也就无需同步了。

    最后我想说的是这种方法简直碉堡了~~~

    附上我用于多线程的测试代码

    importthreadingdefsingleton(cls):

    instance=cls()

    instance.__call__ = lambda: instancereturninstance

    @singletonclassHighlander:

    x= 100

    #Of course you can have any attributes or methods you like.

    defworker():

    hl=Highlander()

    hl.x+= 1

    printhlprinthl.xdefmain():

    threads=[]for _ in xrange(50):

    t= threading.Thread(target=worker)

    threads.append(t)for t inthreads:

    t.start()for t inthreads:

    t.join()if __name__ == '__main__':

    main()

    这里的代码有一点小问题,就是在打印的时候有可能x属性已经被别的线程+1了,所以有可能导致同一个数打印多次,而有的数没有打印,但是不影响最终x属性的结果,所以当所有线程结束之后,属性x最终的值是可以保证正确的。

    Reference:

    展开全文
  • 本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的问题...
  • python单例模式

    2020-07-29 17:06:47
    今天拿下 python 的单例模式 单例模式,通俗的理解就是单个实例对象的模式,就是说这个类只能有一个实例对象 ...python实现单例模式一般有四种,我们按使用频率较多的两种举例(个人见解) 使用 new (父类重写new继
  • 什么是单例模式,为什么要用单例模式,怎么实现单例模式? 只是我们今天要解决的三个问题。 首先,第一点,什么是单例模式? 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某...
  • 语言是共通的,想要用不同语言实现单例模式,首先要清楚什么是单例模式,单例模式即一个类有且仅有一个实例,那么通过python怎么实现一个类只能有一个实例呢。 首先先创建一个类,比如宇宙只有一个地球 class ...
  • python单例设计模式

    2019-02-19 18:23:00
    单例设计模式是怎么来的?在面向对象的程序设计中,当业务并发量非常大时,那么就会出现重复创建相同的对象,每创建一个对象就会开辟一块内存空间,而这些对象其实是一模一样的,那么有没有办法使用得内存对象只创建...
  • 单例模式应该是应用最广泛,实现最简单的一种创建型模式。 特点:全局唯一,允许更改 优缺点 优点: 避免对资源的多重占用,如写入文件操作 节省内存 防止命名空间被污染 缺点: 没有接口,不能继承,与单一职责原则...
  • 那么通过python怎么实现一个类只能有一个实例呢。 class Earth: """ 假如你是神,你可以创造地球 """ print '欢迎来到地球' # 生成一个地球 a = Earth() print id(a) # 再生成一个地球 b = ...
  • Python单例模式

    2019-02-27 22:28:49
    单例模式:通俗地讲,就是无论类实例化多少次,...# 设计模式-单例模式,通俗的讲,单例模式就是无论类怎么实例化, # 它始终只有一个实例存在,多个变量始终指向一个实例 class Animals(): instance = None; ...
  • 通过Singleton模式,全局保证只有一个实例,在python怎么用呢? python的例子 我这里实现了一个pymongo连接的‘缓存’,为了保证在一个进程里面调用只产生一个连接数 Python class ...
  • python 单例模式

    2019-02-28 12:15:00
    单例设计模式是怎么来的?在面向对象的程序设计中,当业务并发量非常大时,那么就会出现重复创建相同的对象,每创建一个对象就会开辟一块内存空间,而这些对象其实是一模一样的,那么有没有办法使用得内存对象只创建...
  • python单例模式

    2017-11-05 17:21:13
    本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的问题?...
  • 本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的问题...
  • __new__实现的串口单例,查了很多单例格式,都只有框架怎么用的案例没有,学习了一下做记录,如果有问题欢迎来拍砖。 import sys import serial import serial.tools.list_ports import threading import time ...
  • 我想创建一个分支线程定时爬去某网站的信息,首先我就想到了使用单例模式,但是Python单例模式并不像java那样一个static就完事了,需要使用不同的机制来实现,在网上找了几篇博客弄明白大概怎么回事,在这里跟大家...
  • 单例设计模式是怎么来的?在面向对象的程序设计中,当业务并发量非常大时,那么就会出现重复创建相同的对象,每创建一个对象就会开辟一块内存空间,而这些对象其实是一模一样的,那么有没有办法使用得内存对象只创建...
  • TN的人问到我怎么实现。我只大概记得是在一个类中定义一个指向为NULL的变量。然后去创建这个类的对象。如果这个对象为空,就新实例化该类的对象,否则就什么也不做。然后返回这个变量。他又问我怎么去传递引用。我一...

空空如也

空空如也

1 2 3
收藏数 60
精华内容 24
关键字:

python怎么实现单例

python 订阅