• python中__init__subclass__方法用法详解


    先看下面代码执行的效果:

    示例代码1:

    1. class Test(object):
    2. def __init_subclass__(cls, **kwargs):
    3. print("__init_subclass__", cls, kwargs)
    4. class A(Test, name="张三", age=16):
    5. pass
    6. """
    7. 代码运行直接输出下面的结果:
    8. __init_subclass__ {'name': '张三', 'age': 16}
    9. """

    运行结果:

            上面代码中定义了一个Test类,然后让A这个类继承它。发现还没有实例化,而是在创建类的时候就有输出结果了。

            对于一个类,如果这个类被作为父类继承,那么会触发其内部的__init_subclass__方法,这里的Test被A继承,那么Test中的__init_subclass__就会被触发。而且看到,里面的cls,就是定义的字类A,也就是继承它的类,**kwargs,就是额外传递的参数。但是发现,第一个参数不是self,而是cls,而且这个cls还不是Test,而是继承它的类。其实这个方法是隐式的被classmethod装饰了。

            有时候想控制类的生成过程,怎么办呢?显然可以通过元类的的方式,但是如果场景比较简单,也没必要使用元类。直接使用__init_subclass__即可

    示例代码2:

    1. class Test(object):
    2. def __init_subclass__(cls, **kwargs):
    3. for k, v in kwargs.items():
    4. type.__setattr__(cls, k, v)
    5. class A(Test, name="张三", age=16):
    6. pass
    7. print(A.name) # 张三
    8. print(A.age) # 16

    运行结果:

            可以看到,在不使用元类的情况下,通过__init_subclass__实现了类的自定义过程。当然这比较简单,也可以实现更复杂的逻辑,在某些场景下,可以替代元类。

    示例代码3:

    1. class TestBase(object):
    2. def __init_subclass__(cls, default_name, **kwargs):
    3. super().__init_subclass__(**kwargs)
    4. cls.default_name = default_name
    5. print(cls.default_name)
    6. class Test(TestBase, default_name="张三"):
    7. pass
    8. class NewTest(Test, default_name="李四"):
    9. pass

    运行结果:

             在上述代码3中,当有子类继承了 TestBase类时,那么 __init_subclass__ 就会调用。内容也很简单,父类 TestBase为它的所有子类都设置了default_name 属性。

            __init_subclass__ 就像是个钩子函数,当子类定义之后触发。

            默认实现 object.__init_subclass__ 不执行任何操作。但默认实现不能传递任何参数,否则报错。
            值得注意的是,示例中的 __init_subclass__ 第一个参数是 cls 而不是常见的 self 。这是因为这个方法隐式地被 @classmethod 装饰。

            __init_subclass__() 是钩子函数,它解决了如何让父类知道被继承的问题。钩子中能改变类的行为,而不必求助与元类或类装饰器。钩子用起来也更简单且容易理解。

  • 相关阅读:
    动态拼接 merge 语句
    H3C mstp+vrrp实验 新华三杯拆解
    PIP安装本地离线包whl
    求先序遍历序列中第(1<=k<=二叉树中结点个数)个结点的值
    SOLIDWORKS 2023交互设计新功能——协作处理团队数据 简化繁琐操作
    目标检测5--旷视YOLOX算法介绍
    WakaTime一个用于跟踪和分析编程时间的工具
    Apifox:详细使用教程,带你轻松拿捏
    JavaScript代码到底是怎么执行的?
    HTTPS 之fiddler抓包--jmeter请求
  • 原文地址:https://blog.csdn.net/weixin_44799217/article/details/126114568