#!/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>

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐