2016-12-19 10 views
1

私は次のコードを実行した場合:代わりにPythonの継承:kwargで引数を混乱

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) 

は、それは「」kwargとして第三引数を解析しているのpythonのように思えますargの代わりにargment cを使用します。私が期待している行動をどうやって得るのですか?

私は明らかに行うことができます。

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 

が、それは恐ろしいあらゆる方法でいるようです。ここで

+0

関数定義に 'c =" c "'を置いても、 'c'はキーワードのみの引数になりません。関数定義と関数呼び出しでの '= whatever'の使用は完全に、まったく100%無関係です。関数定義の '= whatever'は、値が与えられていなければ、引数の値はデフォルトで' whatever'を意味します。 – user2357112

答えて

1

は、それぞれの名前に割り当てられている値を示すために整列あなたのコードから2行、されている:あなたが見ることができるように

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

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

1は、可変引数に一つだけの引数を残し、cに割り当てられているargsリスト。問題は、あなたが想定している方法で引数の2つの "クラス"が存在しないことです。cを "kwarg引数"と呼びますが、実際にはそれほど定義されていません。a以上です。どちらもと'c'の両方のエントリを持つsome_dictと仮定して、B(b="b", **some_dict)と呼ぶことで対処できます。 argsとkwargsの間の定義的な二分法の代わりに、既定値を指定した引数とそうでない引数があります。

あなたが正しいと思うのは、kwargs.pop()です。私のコードは、このような "恐ろしい"例で散らばっています。