您的位置:首页 > 编程语言 > Python开发

python一种用classmethod实现单例模式方法的探讨

2017-05-18 17:27 471 查看
初步实现代码如下:

class Singleton(object):
instance = None
    def __init__(self):
pass
@classmethod
def get_instance(cls):
if Singleton.instance is None:
Singleton.instance = Singleton()
return Singleton.instance

a = Singleton.get_instance()
b = Singleton.get_instance()
print('a id=', id(a))
print('b id=', id(b))


输出:

>>> a id= 39314488
>>> b id= 39314488


通过get_instance函数返回实例初步实现了效果,但是这个类可以实例化,这就达不到单例的效果,见如下的代码:

class Singleton(object):
instance = None
    def __init__(self):
pass
@classmethod
def get_instance(cls):
if Singleton.instance is None:
Singleton.instance = Singleton()
return Singleton.instance

a = Singleton.get_instance()
b = Singleton.get_instance()
c = Singleton()
print('a id=', id(a))
print('b id=', id(b))
print('c id=', id(c))

输出:

>>> a id= 43371992
>>> b id= 43371992
>>> c id= 43384904

c是通过类实例化的id和a、b的不一样。

有没有办法禁止通过类来实例化呢?我们可以在__init__中做文章,在__init__中抛出异常即可禁止实例化了,但是还是有问题,因为get_instance里面就是通过类来实例化的:

@classmethod
def get_instance(cls):
if Singleton.instance is None:
Singleton.instance = Singleton()
return Singleton.instance


除了通过类来实例化就没有其他方法实例化了吗?有,我们可以通过父类object的__new__函数来实例化,
get_instance函数修改为:

@classmethod
def get_instance(cls):
if Singleton.instance is None:
Singleton.instance = object.__new__(Singleton)
return Singleton.instance


完整代码如下:

class Singleton(object):
instance = None
def __init__(self):
raise SyntaxError('can not instance, please use get_instance')

@classmethod def get_instance(cls): if Singleton.instance is None: Singleton.instance = object.__new__(Singleton) return Singleton.instance

a = Singleton.get_instance()
b = Singleton.get_instance()
print('a id=', id(a))
print('b id=', id(b))

c = Singleton()
print('c id=', id(c))



输出:

>>> Traceback (most recent call last):
File "E:/Code/python3/otherTest/classmethodSingleton.py", line 18, in <module>
c = Singleton()
File "E:/Code/python3/otherTest/classmethodSingleton.py", line 5, in __init__
raise SyntaxError('can not instance, please use get_instance')
SyntaxError: can not instance, please use get_instance
>>> a id= 39125064
>>> b id= 39125064

从完整代码和输出可以看出只能通过get_instance获取实例,不能通过类来实例化,通过类来实例化会报异常。

PS:同样的通过staticmethod也能实现单例模式,见python一种用staticmethod实现单例模式方法的探讨
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息