本文发自 http://www.binss.me/blog/talk-about-the-singleton-pattern-in-python/,转载请注明出处。

什么是单例模式?

我的理解是:保证该类仅能够产生一个实例。当该类没有实例时,创建一个并返回。而当该类有实例时,始终返回该实例。

在之前写的代码中,我是这样实现单例的:

def singleton(cls):
    instances = {}

    def _singleton(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return _singleton

这是一个装饰器,使用该函数装饰的类即为单例类。使用方法如下:

@singleton
class IWantToBeAlone:
    def __init__(self):
        self.count = 0

    def add(self):
        self.count += 1

    def getCount(self):
        return self.count

a = IWantToBeAlone()
a.add()
b = IWantToBeAlone()
print a
print b
print a.getCount()
print b.getCount()

输出为

<__main__.IWantToBeAlone instance at 0x1004c9368>
<__main__.IWantToBeAlone instance at 0x1004c9368>
1
1

显然,a和b指向的的是同一个对象,即单例。

然后今天复习设计模式的时候看到一种说法:

Python不需要单例模式。使用模块(module)即可。

意思是,module的导入有且只有一次,所以可以把变量和函数放进一个module里,使用它来实现单例。

于是我试了一下:

#singleton.py
count = 0

def add():
    global count
    count += 1

def getCount():
    global count
    return count

使用:

#test.py
import singleton
a = singleton
a.add()
b = singleton
print a
print b
print a.getCount()
print b.getCount()

结果:

<module 'singleton' from '/Users/bin/Desktop/singleton.pyc'>
<module 'singleton' from '/Users/bin/Desktop/singleton.pyc'>
1
1

也实现了单例!

然后网上的小伙伴们提出了问题:

  1. 如何处理环路导入?

  2. 如何实现继承?

是的。。。问题似乎的确如此。不过不管怎么样,学到了一种单例的新姿势。

参考

http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/31887#31887