Python--metaclass 元类 及对应实现的单例模式
代码摘自书籍<<人人都懂设计模式>>
元类(C-8):
class CustomMetaclass(type): def __init__(cls, what, bases=None, dict=None): # 这个方法只会调用一次 print('CustomMetaclass.__init__ cls:', cls) super().__init__(what, bases, dict) def __call__(cls, *args, **kwargs): # 每次实例化对象都会调用此方法 print('CustomMetaclass.__call__ args:', args, kwargs) self = super(CustomMetaclass, cls).__call__(*args, **kwargs) print('CustomMetaclass.__call__ self:', self) return self class CustomClass(metaclass=CustomMetaclass): def __init__(self, *args, **kwargs): print('CustomClass.__init__ self:', self) super().__init__() def __new__(cls, *args, **kwargs): self = super().__new__(cls) print('CustomClass.__new__ self:', self) return self def __call__(self, *args, **kwargs): print('CustomClass.__call__ args:', args) obj = CustomClass('Meta arg1', 'Meta arg2', kwarg1=1, kwarg=2) print(type(CustomClass)) print(obj) obj('arg1', 'arg2') obj2 = CustomClass('Meta obj2 arg1', 'Meta obj2 arg2', kwarg1=1, kwarg=2) print(obj) obj2('obj2 arg1', 'obj2 arg2') ''' 输出结果 CustomMetaclass.__init__ cls: <class '__main__.CustomClass'> CustomMetaclass.__call__ args: ('Meta arg1', 'Meta arg2') {'kwarg1': 1, 'kwarg': 2} CustomClass.__new__ self: <__main__.CustomClass object at 0x000001B4B38AB630> CustomClass.__init__ self: <__main__.CustomClass object at 0x000001B4B38AB630> CustomMetaclass.__call__ self: <__main__.CustomClass object at 0x000001B4B38AB630> <class '__main__.CustomMetaclass'> <__main__.CustomClass object at 0x000001B4B38AB630> CustomClass.__call__ args: ('arg1', 'arg2') CustomMetaclass.__call__ args: ('Meta obj2 arg1', 'Meta obj2 arg2') {'kwarg1': 1, 'kwarg': 2} CustomClass.__new__ self: <__main__.CustomClass object at 0x000001B4B38AB5F8> CustomClass.__init__ self: <__main__.CustomClass object at 0x000001B4B38AB5F8> CustomMetaclass.__call__ self: <__main__.CustomClass object at 0x000001B4B38AB5F8> <__main__.CustomClass object at 0x000001B4B38AB630> CustomClass.__call__ args: ('obj2 arg1', 'obj2 arg2') '''
单例设计模式(5-3):
class Singleton2(type): def __init__(cls, what, bases=None, dict=None): print('Singleton2.__init__ start') super().__init__(what, bases, dict) print('Singleton2.__init__ end') cls._instance = None def __call__(cls, *args, **kwargs): print('Singleton2.__call__ start') if cls._instance is None: print('Singleton2.__call__ super') cls._instance = super().__call__(*args, **kwargs) print('Singleton2.__call__ end') return cls._instance class CustomClass(metaclass=Singleton2): def __init__(self, name): self.__name = name def get_name(self): return self.__name tony = CustomClass('Tony') karry = CustomClass('Karry') print(tony.get_name(), karry.get_name()) print('id(tony):', id(tony), 'id(karry):', id(karry)) print('tony==karry:', tony == karry) ''' 输出结果 Singleton2.__init__ start Singleton2.__init__ end Singleton2.__call__ start Singleton2.__call__ super Singleton2.__call__ end Singleton2.__call__ start Singleton2.__call__ end Tony Tony id(tony): 2488074155680 id(karry): 2488074155680 tony==karry: True '''