2017-02-22 13 views
8

この質問は、Inherit namedtuple from a base class in pythonの反対の質問です。ここでの目的は、namedtupleのサブクラスを継承することであり、その逆もありません。通常の継承では、この作品namedtuple基底クラスから継承する - Python

>>> Z(1,2,3,4) 
<__main__.Z object at 0x10fcad950> 

しかし、基底クラスが namedtupleある場合:

class Y(object): 
    def __init__(self, a, b, c): 
     self.a = a 
     self.b = b 
     self.c = c 


class Z(Y): 
    def __init__(self, a, b, c, d): 
     super(self.__class__, self).__init__(a, b, c) 
     self.d = d 

を[出力]

from collections import namedtuple 

X = namedtuple('X', 'a b c') 

class Z(X): 
    def __init__(self, a, b, c, d): 
     super(self.__class__, self).__init__(a, b, c) 
     self.d = d 

[出]:

>>> Z(1,2,3,4) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: __new__() takes exactly 4 arguments (5 given) 

質問、は、namedtuplesをPythonの基本クラスとして継承することは可能ですか?そうです、どうですか?

答えて

12

することができますが、あなたは__init__前に暗黙的に呼び出され__new__を上書きする必要があります。

class Z(X): 
    def __new__(cls, a, b, c, d): 
    self = super(Z, cls).__new__(cls, a, b, c) 
    self.d = d 
    return self 

>>> z = Z(1, 2, 3, 4) 
>>> z 
Z(a=1, b=2, c=3) 
>>> z.d 
4 

しかしdだけの独立した属性になります!

>>> list(z) 
[1, 2, 3] 
+0

が、私は 'self.append(d)を'行うことができます。たとえば、入力値のいくつかは、次のような作品を を計算するのではなく、直接供給されることになっている 最大のケースに対処するには? – alvas

+0

@alvasいいえ、 'namedtuple'は基本的に' tuple'です(設計によって不変なので 'append'はありません)。 – MSeifert

+0

@Mseifertありがとう!しかし、=( – alvas

3

は、私はあなたがして引数の数を調整し、元の名前のタプル内のフィールド のすべてを含む schwobasegglは、上記のとおり__new__を使用することにより、あなたが望むものを達成することができると思います。

from collections import namedtuple 

class A(namedtuple('A', 'a b c computed_value')): 
    def __new__(cls, a, b, c): 
     computed_value = (a + b + c) 
     return super(A, cls).__new__(cls, a, b, c, computed_value) 

>>> A(1,2,3) 
A(a=1, b=2, c=3, computed_value=6) 
関連する問題