在类定义中添加参数

时间:2017-06-20 16:14:18

标签: python inheritance metaclass

我在Python中遇到了这种设计模式,想知道是否有人可以解释,因为我之前从未见过

def func():
   pass

class Child(Parent, f=func):
   pass

不确定这里发生了什么。如果Parent有元类定义,它会更改类构造函数以允许传递参数,这是否可行?任何帮助都表示赞赏并抱歉含糊不清

2 个答案:

答案 0 :(得分:3)

这适用于Python 3.6,在父级上使用__init_subclass__

class Parent:
    def __init_subclass__(self, f, **kwargs):
        super().__init_subclass__(**kwargs)
        print(f)

def func():
    pass

class Child(Parent, f=func):
    pass

输出:

<function func at 0x7f48207cae18>

答案 1 :(得分:1)

类定义中的额外命名参数将传递给类构造函数方法 - 即元类__new__

In [1]: class M(type):
   ...:     def __new__(metacls, name, bases, namespace, **kwargs):
   ...:         print(f'At metaclass, {kwargs}')
   ...:         return super().__new__(metacls, name, bases, namespace)
   ...:     

In [2]: class A(metaclass=M, f="hello world"): pass
At metaclass, {'f': 'hello world'}

因此,即使在Python 3.6之前,自定义元类也可能会使用它。但是n Python 3.6, the __init_subclass__ addition使得这样的参数变得更简单,因此更有用 - 因为不需要自定义元类。

请注意,自定义类层次结构中的__init_subclass__方法负责最终调用object.__init_subclass__ - 它不接受任何命名参数。因此,如果要创建使用__init_subclass__的类层次结构,则每个此类方法应在调用kwargs之前从super().__init_subclass__中删除它们以“消耗”其特定参数。 __new__本身的__init__type方法(默认元类)只是忽略任何命名的args。