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')
'''
View Code

单例设计模式(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
'''
View Code

 

posted @ 2021-09-25 18:01  liDB  阅读(47)  评论(0编辑  收藏  举报