当我阅读Python Cookbook 3Edition食谱9.18时,遇到带有父类和一些可选参数的类定义,当我查找它时,我知道python 3.6为父类添加了新功能__init_subclass __()方法,但是这本书是基于Python3.3编写的,那么除了元类之外,还有什么方法会采用这些参数?
类定义在这里:
class Spam(Base, debug=True, typecheck=False):
...
我知道元类可以在其__prepare __,__ new __,__ init__方法中接受其他可选参数,但是Base是父类,这些参数在何处
答案 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__
中使用显式的命名参数。