继承自namedtuple基类 - Python

时间:2017-02-22 08:10:38

标签: python oop inheritance super namedtuple

这个问题与Inherit namedtuple from a base class in python相反,其目的是从一个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(Z, self).__init__(a, b, c)
        self.d = d

[OUT]:

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

但如果基类是namedtuple

from collections import namedtuple

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

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

[OUT]:

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

问题,是否可以在Python中继承namedtuples作为基类?是这样,怎么样?

4 个答案:

答案 0 :(得分:21)

您可以,但必须覆盖['a','c a','c a','c a','c 1234 abc'] 之前隐式调用的__new__

__init__

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

答案 1 :(得分:7)

我认为你可以通过包括所有领域来实现你想要的 在原始命名元组中,然后调整参数的数量 使用__new__作为schwobaseggl建议如上。例如,要解决 max的情况,其中一些输入值将被计算 而不是直接提供,以下工作:

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)

答案 2 :(得分:1)

两年后,我来到这里时遇到了完全相同的问题。
我个人认为@property装饰器会更适合这里:

from collections import namedtuple

class Base:
    @property
    def computed_value(self):
        return self.a + self.b + self.c

# inherits from Base
class A(Base, namedtuple('A', 'a b c')):
    pass

cls = A(1, 2, 3)
print(cls.computed_value)
# 6

答案 3 :(得分:0)

不要严格地考虑继承,因为 namedtuple 是一个函数,另一种方法是将它封装在一个新函数中。

问题变成了:“我们如何构造一个默认具有属性 a, b, c 的命名元组,以及可选的一些附加属性?”

def namedtuple_with_abc(name, props=[]):
     added = props if type(props) == type([]) else props.split()
     return namedtuple(name, ['a', 'b', 'c'] + added)

X = namedtuple_with_abc('X')
Z = namedtuple_with_abc('Z', 'd e')

>>> X(1, 2, 3)
X(a=1, b=2, c=3)

>>> Z(4, 5, 6, 7, 8)
Z(a=4, b=5, c=6, e=7, f=8)