• Python中如何控制类的实例化过程


    python中控制类的实例化过程有两种方式: 1.通过类中__new__方法,  2.通过元类编程

    下面以设计单例模式为示例,来呈现控制类实例化的两种方式

    首先, 单例模式需要确保一个类只有一个实例对象, 那么就需要在类的实例化过程中控制实例对象的生成逻辑

    一. 基于__new__方法实现单例模式

    1.1 预备知识: 理解类中new方法,init方法,call方法

      1) __new__方法负责创建实例对象(创建对象时调用)

      2) __init__方法负责对实例对象进行初始化

      3) 如果__new__方法没有返回实例对象, 那么__init__方法是不会被调用的

      4) 定义__call__方法后,实例对象可以像函数那个被调用

    1.2 代码实现

    # -*- coding: utf-8 -*-
    
    
    class Singleton(object):
        # 在__new__方法中控制类的实例化过程
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, "_instance"):
                cls._instance = super().__new__(cls)
    
            return cls._instance
    
    
    # 创建两个实例对象, 对比其对象id是否相同
    s1 = Singleton()
    s2 = Singleton()
    print(id(s1) == id(s2))  # True

    二. 基于元类编程实现单例模式

    2.1 预备知识: 如何理解元类

      1) python中一切皆对象, 类也是对象, 元类就是类的类

      2) 通过type可以动态的创建类, 例如 MyClass = type("MyClass ", (object, ), {})

      3) type是python的内建元类, 开发者也可以自定义元类

      4) 自定义元类后, 在创建类时开发者可以改变类的生成过程

    2.2 代码实现

    # -*- coding: utf-8 -*-
    
    # 自定义元类
    class MyMetaClass(type):
        instance = {}
    
        def __init__(cls, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
        # cls被调用时会调用__call__方法, 而cls被调用时正是cls类的实例化过程
        def __call__(cls, *args, **kwargs):
            if cls not in cls.instance:
                cls.instance[cls] = super().__call__(*args, **kwargs)
    
            return cls.instance
    
    
    class Demo(metaclass=MyMetaClass):
        pass
    
    
    # 创建两个实例对象, 对比其对象id是否相同
    a = Demo()
    b = Demo()
    print(id(a) == id(b))  # True

    最后小结:

      类的实例化过程, 可以通过__new__方法来实现, 也可以将类的实例化过程剥离出来,委托给元类来做

  • 相关阅读:
    C++ 编写strcpy函数
    JavaScript抽象类及Class.create备忘
    读:<测试一下你解决问题的逻辑思维及算法能力>后
    JavaScript AJAX类
    MOSS ad组的获取及Hashtable作缓存总结
    Js获取元素位置及动态生成元素的练习备忘
    NET许可证及License
    Javascript获取元素位置及其它
    hdu 149850 years, 50 colors 最大匹配
    poj 2513 Colored Sticks 字典树
  • 原文地址:https://www.cnblogs.com/reconova-56/p/15177461.html
Copyright © 2020-2023  润新知