Python单例的实现与分析
#!/usr/bin/env pythonclass Singleton(type):'''单例--用法:__metaclass__=Singleton'''def __init__(cls, name, bases, dic):'''初始化'''return super(Singleton, cls).__init__(name, b
·
#!/usr/bin/env python
class Singleton(type):
'''单例--用法:__metaclass__=Singleton'''
def __init__(cls, name, bases, dic):
'''初始化'''
return super(Singleton, cls).__init__(name, bases, dic)
def __call__(self, *args, **kwargs):
'''类生成对象时调用'''
if not getattr(self, '_instance', None):
self._instance = super(Singleton, self).__call__(*args, **kwargs)
return self._instance
class Singleton2(object):
'''单例2--用法:继承'''
def __init__(self, *args, **kwargs):
'''初始化,<span style="color:#cc0000;">这个函数每次实例化对象都会调用,故用此方法不能有__init__函数</span>'''
return super(Singleton2, self).__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
'''构造函数'''
if not getattr(cls, '_instance', None):
cls._instance = super(Singleton2, cls).__new__(cls, *args, **kwargs)
return cls._instance
def inspector(cls):
'''单例装饰器--用法:@inspector,<span style="color:#cc0000;">运用此方法,类名被替换成_insp函数,故单例类不能通过super调用父类方法</span>'''
def _insp(*args, **kwargs):
if not getattr(cls, '_instance', None):
cls._instance = cls(*args, **kwargs)
return cls._instance
return _insp
class MyTest(object):
__metaclass__ = Singleton
def __init__(self, *args, **kwargs):
return super(MyTest, self).__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
return super(MyTest, cls).__new__(cls, *args, **kwargs)
class MyTest2(Singleton2):
def __init__(self, *args, **kwargs):
return super(MyTest2, self).__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
return super(MyTest2, cls).__new__(cls, *args, **kwargs)
@inspector
class MyTest3(object):
"""
<span style="color:#666666;">def __init__(self, *args, **kwargs):
print 'in MyTest3 __init__'
print 'args:',str(args), ' type:',type(args)
print 'MyTest3:',MyTest3, ' type:',type(MyTest3)
res = super(MyTest3, self).__init__(*args, **kwargs)
print 'res:',res, ' type:',type(res)
return res
def __new__(cls, *args, **kwargs):
print 'in MyTest3 __new__'
return super(MyTest3, cls).__new__(cls, *args, **kwargs)</span>
"""
def printd(self):
print 'in MyTest3 printd:',self
print 'in MyTest3 printd _instance:',self
<span style="color:#cc0000;">上述三种方法中,推荐用第一种,因为第二种方法要求单例子类不能有自己的__init__函数,否则会多次调用这个函数,这样就会改变部分状态(取决于在__init__函数中所做的操作);而第三种要求单例类中不能通过super调用父类的函数,因为super函数用的类名已经替换为函数名了.</span>
更多推荐
已为社区贡献3条内容
所有评论(0)