zoukankan      html  css  js  c++  java
  • Python利用元类来控制实例创建

    问题:

    改变实例创建方式,以此来实现单例模式,缓存或者其他类似的特性。

    解决方法:

    如果想定制化创建实例的过程,可以通过定制一个元类并以某种方式重新实现它的__call__()方法。

    使用元类的单例模式实现:

    class Singleton(type):
        def __init__(self, *args, **kwargs):
            self.__instance = None
            super().__init__(*args, **kwargs)
    
        def __call__(self, *args, **kwargs):
            if self.__instance is None:
                self.__instance = super().__call__(*args, **kwargs)
                return self.__instance
            else:
                return self.__instance
    
    class Spam(metaclass=Singleton):
        def __init__(self):
            print("Creating Spam")
    
    a = Spam()
    b = Spam()
    print(a is b)
    c = Spam()
    print(a is c)

    运行结果:

    Creating Spam
    True
    True

    不使用元类的单例模式实现:

    class _Spam:
        def __init__(self):
            print("Creating Spam")
    
    _spam_instance = None
    
    def Spam():
        global _spam_instance
        if _spam_instance is not None:
            return _spam_instance
        else:
            _spam_instance = _Spam()
            return _spam_instance
    
    a = Spam()
    b = Spam()
    print(a is b)
    c = Spam()
    print(a is c)

    运行结果:

    Creating Spam
    True
    True

    创建缓存实例:(不使用元类方法链接:https://www.cnblogs.com/weswes/p/10007794.html

    import weakref
    
    class Cached(type):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.__cache = weakref.WeakValueDictionary()
    
        def __call__(self, *args, **kwargs):
            if args in self.__cache:
                return self.__cache[args]
            else:
                obj = super().__call__(*args, **kwargs)
                self.__cache[args] = obj
                return obj
    
    class Spam(metaclass=Cached):
        def __init__(self, name):
            print("Creating Spam({!r})".format(name))
            self.name = name
    
        def __call__(self, *args, **kwargs):
            print(999)
    
    a = Spam("Guido")
    b = Spam("Diana")
    c = Spam("Guido")
    print(a is b)
    print(a is c)

    运行结果:

    Creating Spam('Guido')
    Creating Spam('Diana')
    False
    True
  • 相关阅读:
    初涉Django与MySQL连接
    Mysql数据库操作常用命令
    解决远程登录MYSQL数据库
    全集网影片下载
    LR学习资料
    LR性能测试说明
    fiddler
    Axure(快速原型设计工具)
    httpwatch
    Appscan(安全性测试工具)
  • 原文地址:https://www.cnblogs.com/weswes/p/10013276.html
Copyright © 2011-2022 走看看