如何将必需的关键字参数添加到派生类的构造函数?

时间:2019-09-16 16:26:16

标签: python arguments keyword-argument pep-3102

我的情况与this question几乎相同,只是我需要关键字参数。

我想在派生类中添加必需关键字参数,但不知道如何处理。尝试显而易见的

class ClassA(some.package.Class):

    def __init__(self, *args, **kwargs):
        super(ClassA, self).__init__(*args, **kwargs)

class ClassB(ClassA):

    def __init__(self, *args, a, b, c, **kwargs):
        super(ClassB, self).__init__(*args, **kwargs)
        self.a=a
        self.b=b
        self.c=c

失败,因为我无法列出ClassB的{​​{1}}那样的参数。还有

__init__

当然不起作用,因为未指定新关键字。

如何为派生类的class ClassB(ClassA): def __init__(self, *args, **kwargs): super(ClassA, self).__init__(*args, **kwargs) self.a=a self.b=b self.c=c 添加必需关键字参数?

相似的问题:How do I add keyword arguments to a derived class's constructor in Python?

1 个答案:

答案 0 :(得分:3)

不提供默认值,并且关键字参数是必需的:

class ClassB(ClassA):
    def __init__(self, *args, a, b, c, **kwargs):
        super().__init__(*args, **kwargs)  # No need to pass arguments to super in Py3
        self.a = a
        self.b = b
        self.c = c

仍然要求它们仅是关键字,因为它们在*args参数之后

此功能与PEP 3102中的仅关键字自变量同时添加,其中指出:

  

仅关键字参数不需要具有默认值。由于Python要求将所有参数都绑定到值,并且将值绑定到仅关键字参数的唯一方法是通过关键字,因此此类参数是“必需关键字”参数。此类参数必须由调用方提供,并且必须通过关键字提供。

为清楚起见,仅关键字参数(必需或默认)是仅Python 3的功能。如果您尝试在Python 2上执行此操作,则不可能让Python为您完成工作,您只需要自己执行检查即可。转到Python 3; Python 2将于2019年底到期(没有补丁,甚至没有安全性),因此无论如何,新代码都应以Python 3为目标。

仅作记录,您在Python 2上使用的代码就很糟糕:

class ClassB(ClassA):
    def __init__(self, *args, **kwargs):
        try:
            self.a = kwargs.pop('a')
            self.b = kwargs.pop('b')
            self.c = kwargs.pop('c')
        except KeyError as e:
            # Convert to TypeError to match Python 3 behavior
            raise TypeError("__init__ missing required keyword-only argument: {!s}".format(e))
        super(ClassB, self).__init__(*args, **kwargs)

缺点是它没有出现在初始化器/类签名中,并且手动弹出这样的参数会更昂贵(在编写的代码和运行时中)。