在python 3.6之前,是否有任何像__init_subclass__()这样的方法



当我阅读Python Cookbook 3rd Edition配方9.18时,我遇到了一个带有父类和一些可选参数的类定义,我查了一下。我知道 Python 3.6 为父类添加了__init_subclass__()方法的新功能,但这本书是基于 Python 3.3 编写的,那么除了metaclass之外,还有什么方法会接受这些参数呢?

类定义在这里:

class Spam(Base, debug=True, typecheck=False):
    ...

我知道元类可以在其__prepare____new____init__方法中接受其他可选参数,但Base父类,这些参数去哪儿了?

__init_subclass__是对Python 3.6的补充,以减少对自定义元类的需求,因为它的许多用途都是"矫枉过正"。这个想法是为包含__init_subclass__方法的(普通的,非元的(基类创建的每个子类,都将被调用,并将新的子类作为第一个参数:

class Base:
   def __init_subclass__(subclass, debug=None, typecheck=None, **kwargs):
        # do stuff with the optional debug and typecheck arguments
        # Pass possible arguments not consumed here to superclasses, if any:
        super().__init_subclass__(**kwargs)

并且根本不需要元类 - 默认元类的__prepare____init____new__ - type - 将忽略以这种方式传递的任何命名参数。但是,如果未知的命名参数到达对象中的默认__init_subclass__,则会引发它 - 上面的模式将使用这些参数,将它们从 kwargs 中删除。如果您正在处理未知的命名参数,只需像普通字典一样处理 kwargs - 无需在__init_subclass__中使用显式命名参数。

他们像往常一样转到元类的__prepare__方法。仅仅因为Base没有指定元类并不意味着它没有元类。默认元类为 type

在 Python 3.6 中添加__init_subclass__ type只是节省了您定义自定义元类的工作量,以便实现等效的__init_subclass__自己。

最新更新