• Python 单例模式


    相信大家学过编程语言对单例模式应该都很熟悉吧。今天就说一下在Python 中单例模式的写法。

    1. 使用 __new__ 方式

     1 class mySingleton():
     2     def __new__(cls, *args, **kwargs):
     3         if not hasattr(cls, '_instance'):
     4             cls._instance = super().__new__(cls, *args, **kwargs)
     5         return cls._instance
     6 
     7 
     8 ms1 = mySingleton()
     9 ms2 = mySingleton()
    10 print(id(ms1) == id(ms2))

    >>> True

    2. 装饰器

     1 def singleton_decorate(func):
     2     intance_dict = {}
     3 
     4     def get_instance(*args, **kwargs):
     5         # if not intance_dict:
     6         if "instance" not in intance_dict:
     7             intance_dict["instance"] = func()
     8         return intance_dict["instance"]
     9 
    10     return get_instance
    11 
    12 
    13 @singleton_decorate
    14 class singleton():
    15     pass
    16 
    17 
    18 s1 = singleton()
    19 s2 = singleton()
    20 print(id(s1) == id(s2))

    3. 元类

     1 class Singleton(type):
     2     instance = {}
     3 
     4     def __call__(cls, *args, **kwargs):
     5         if "instance" not in cls.instance:
     6             cls.instance["instance"] = super().__call__(*args, **kwargs)
     7         return cls.instance["instance"]
     8 
     9 
    10 class myCls(metaclass=Singleton):
    11     pass
    12 
    13 
    14 mc1 = myCls()
    15 mc2 = myCls()
    16 print(id(mc1) == id(mc2))

    这是三种创建单例模式的方法。只是扩展一下。代码之中用到了 __new__, __call__ 方法,其中还有 __init__ 方法,他们的作用是什么?

    __new__:

    对象的创建会调用这个方法, 它是一个静态方法返回一个类对象, 默认情况下是不需要写的,可以 overide。

    __init__:

    说 __new__ 就必须说 __init__ 方法, 因为 __new__ 是创建对象,但是并没有对对象进行初始化,而 __init__ 作用便是初始化对象, 加载对象数据, 也可以 overide。

    __call__ :

    我现阶段了解的 __call__ 方法是, 类可以调用, 就是 a  = A() , A() 是生成对象,那 a() 这么呢, 如果有 __call__ 方法的话, a() 就是调用 __call__ 方法。

    上面代码中 myCls 就是 Singleton 的对象,因为 myCls 的元类是 Singleton ,在这里解释一下元类吧。

    元类:

    我们都知道 类实例 是 类 的对象, 那么 类 又是谁的对象呢?答案就是:元类, 元类的对象便是类,所以上面 元类这种单例模式就很好解释了。

    ps: 今天就和大家分享到这里,如有不对,还请指正,谢谢。

    共勉!

  • 相关阅读:
    阿里云重磅发布DMS数据库实验室 免费体验数据库引擎
    阿里云移动端播放器高级功能---直播时移
    图解SQL的inner join、left join、right join、full outer join、union、union all的区别
    索引覆盖分析
    case when 性能优化
    Eclipse断点种类
    Eclipse高效率开发技巧
    VS Code编辑器
    正则表达式
    JDBC编程之预编译SQL与防注入式攻击以及PreparedStatement的使用教程
  • 原文地址:https://www.cnblogs.com/JulyShine/p/9998338.html
Copyright © 2020-2023  润新知