什么是__init_subclass__

class Hook:

    def __init_subclass__(cls, **kwargs):
print("__init_subclass__", cls, kwargs) class A(Hook, name="satori", age=16):
pass
"""
__init_subclass__ <class '__main__.A'> {'name': 'satori', 'age': 16}
"""

首先我们定义了一个Hook类,然后让A这个类继承它。发现我们还没有没有实例化,而是在创建类的时候就有输出结果了。

对于一个类,如果这个类被作为父类继承,那么会触发其内部的__init_subclass__方法,这里的Hook被A继承,那么Hook中的__init_subclass__就会被触发。而且看到,里面的cls,就是我们的A,也就是继承它的类,**kwargs,就是我们额外传递的参数。

但是我们发现,第一个参数不是self,而是cls,而且这个cls还不是我们的Hook,而是继承它的类。其实这个方法是隐式的被classmethod装饰了

用法

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

class Hook:

    def __init_subclass__(cls, **kwargs):
for k, v in kwargs.items():
type.__setattr__(cls, k, v) class A(Hook, name="satori", age=16):
pass print(A.name) # satori
print(A.age) # 16

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

python中的__init_subclass__是什么?的更多相关文章

  1. 【Python深入】Python中继承object和不继承object的区别

    python中定义class的时候,有object和没有object的不同?例如: class Solution(object): class Solution(): 这俩的区别在于—————— 在p ...

  2. python中的迭代器与生成器

    迭代器 迭代器的引入 假如我现在有一个列表l=['a','b','c','d','e'],我想取列表中的内容,那么有几种方式? 1.通过索引取值 ,如了l[0],l[1] 2.通过for循环取值 fo ...

  3. python学习之【第十篇】:Python中的内置函数

    1.前言 内置函数,就是Python内部预先定义好的函数,可以直接使用,Python中内置函数有以下这么多个: 2.map() 描述: map() 会根据提供的函数对指定序列做映射.第一个参数 fun ...

  4. python中的type和object详解

    关于这篇博客 这篇博客主要描述Python的新风格对象(new-style objects),如下: <type 'type'>和<type 'object'>分别是什么? 用 ...

  5. Python 中的面向对象编程

    面向对象编程(Object-oriented programming, OOP)是一种基于对象概念的编程范式,可包含属性(attribute)形式的数据以及方法(method)形式的代码.另一种对 O ...

  6. [转]Python中的str与unicode处理方法

    早上被python的编码搞得抓耳挠腮,在搜资料的时候感觉这篇博文很不错,所以收藏在此. python2.x中处理中文,是一件头疼的事情.网上写这方面的文章,测次不齐,而且都会有点错误,所以在这里打算自 ...

  7. python中的Ellipsis

    ...在python中居然是个常量 print(...) # Ellipsis 看别人怎么装逼 https://www.keakon.net/2014/12/05/Python%E8%A3%85%E9 ...

  8. python中的默认参数

    https://eastlakeside.gitbooks.io/interpy-zh/content/Mutation/ 看下面的代码 def add_to(num, target=[]): tar ...

  9. Python中的类、对象、继承

    类 Python中,类的命名使用帕斯卡命名方式,即首字母大写. Python中定义类的方式如下: class 类名([父类名[,父类名[,...]]]): pass 省略父类名表示该类直接继承自obj ...

随机推荐

  1. centos源码安装mysql5.7

    http://blog.csdn.net/langzi7758521/article/details/51435985

  2. wdScrollTab

    wdScrollTab是一个采用jQuery实现的Tab面板,当标签太多超出页面时会自动滚动.支持iframe.ajax调用和动态加载内容.

  3. 红队(red team)

    红队资源相关 https://threatexpress.com/redteaming/resources/ 红队相关技术 https://github.com/bluscreenofjeff/Red ...

  4. Rowlock、UPDLOCK

      ROWLOCK 使用行级锁,而不使用粒度更粗的页级锁和表级锁. UPDLOCK 读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句或事务的结束.UPDLOCK 的优点是允许您读取数据(不阻塞 ...

  5. RocketMQ之十:RocketMQ消息接收源码

    1. 简介 1.1.接收消息 RebalanceService:均衡消息队列服务,负责通过MQClientInstance分配当前 Consumer 可消费的消息队列( MessageQueue ). ...

  6. CSRF类型

    按照请求类型来区分.分为:GET类型和POST类型 按照攻击类型分类,CSRF可分为:HTML CSRF攻击,JSOM HiJacking攻击和FIash CSRF攻击 HTML CSRF攻击 HTM ...

  7. 【操作系统】【C/C++开发】内存管理

    内存管理 操作系统对内存的划分和动态分配,就是内存管理的概念.有效的内存管理在多道程序设计中非常重要,不仅方便用户使用存储器.提高内存利用率,还可以通过虚拟技术从逻辑上扩充存储器.内存管理的功能有: ...

  8. Netty对常用编解码的支持

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! Netty对编解码的支持 打开Netty的源码,它对很多的编码器都提 ...

  9. POSTGRESQL日期函数大全

    一:各个数据中的连接符 SqlServer的连接符:+(加号) Sqlite的连接符:.(点) PostgreSQL的连接符:||(或) 二: 今天在PostgreSQL计算日期的时候,翻了一些资料, ...

  10. STL map 常见用法详解

    <算法笔记>学习笔记 map 常见用法详解 map翻译为映射,也是常用的STL容器 map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器) 1. map 的定义 / ...