Python继承:将arg与kwarg混淆

时间:2016-12-19 19:14:15

标签: python-2.7 inheritance

如果我运行以下代码:

class A(object) :

    def __init__(self, x, y, z=3.0):
        self.x = x
        self.y = y
        self.z = z

class B(A):

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


if __name__=="__main__":

    thing = B("a", "b", 1, 2)

    print thing.x # expect 1
    print thing.y # expect 2
    print thing.z # expect 3
    print thing.a # expect a
    print thing.b # expect b
    print thing.c # expect c

相反,我得到:

Traceback (most recent call last):
  File "H:/Python/Random Scripts/python_inheritance.py", line 23, in <module>
    thing = B(1,2,"a","b")
  File "H:/Python/Random Scripts/python_inheritance.py", line 15, in __init__
    super(B, self).__init__(*args, **kwargs)
TypeError: __init__() takes at least 3 arguments (2 given)

似乎python正在将第三个参数“a”解析为kwarg argment而不是arg。我如何得到我期望的行为?

我显然可以这样做:

class B(A):

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

但它似乎在各方面都很可怕。

1 个答案:

答案 0 :(得分:1)

以下是代码中的两行,对齐以显示为每个名称指定的值:

def __init__(self, a,   b,  c="c", *args, **kwargs):

        thing = B("a", "b", 1,     2)

如您所见,1已分配给c,在可变参数args列表中只留下一个参数。问题是没有两个&#34;类&#34;以你所假设的方式论证:你称c为&#34; kwarg论证&#34;它不是真正定义的,不仅仅是a。如果B(b="b", **some_dict)同时拥有some_dict'a'条目,则可以致电'c'来解决这两个问题。而不是args和kwargs之间的定义二分法,只有指定默认值的参数和没有指定默认值的参数。

我认为你是对的,kwargs.pop()是你最好的选择。我的代码充满了这样的&#34;可怕的&#34;实例