在python 3.6之前是否有类似__init_subclass __()的方法

时间:2019-05-31 08:58:26

标签: python python-3.x class

当我阅读Python Cookbook 3Edition食谱9.18时,遇到带有父类和一些可选参数的类定义,当我查找它时,我知道python 3.6为父类添加了新功能__init_subclass __()方法,但是这本书是基于Python3.3编写的,那么除了元类之外,还有什么方法会采用这些参数?

类定义在这里:

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

我知道元类可以在其__prepare __,__ new __,__ init__方法中接受其他可选参数,但是Base是父类,这些参数在何处

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

__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__的{​​{1}},__init____new__将忽略传入的任何命名参数这条路。但是,如果到达未知的命名参数,则对象中的默认type会升高-上面的模式将使用这些参数,并将其从kwargs中删除。如果您要处理未知的命名参数,则可以像处理普通字典一样处理kwarg-无需在__init_subclass__中使用显式的命名参数。