type not must multiple method init__ def classobj argument python oop inheritance super namedtuple

not - super python 3



Heredar de una clase de base nombrada en tupla-Python (2)

Esta pregunta plantea lo contrario de Heredar el grupo nombrado de una clase base en python , donde el objetivo es heredar una subclase de un grupo nombrado y no al contrario.

En la herencia normal, esto funciona:

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

[afuera]:

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

Pero si la clase base es una namedtuple :

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

[afuera]:

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

La pregunta, ¿ es posible heredar unidades de nombre como una clase base en Python? Es así, ¿cómo?


Creo que puede lograr lo que desea al incluir todos los campos en la tupla con el nombre original, y luego ajustar el número de argumentos usando __new__ como lo sugiere schwobaseggl arriba. Por ejemplo, para abordar el caso de max, donde algunos de los valores de entrada deben calcularse en lugar de proporcionarse directamente, los siguientes trabajos:

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)


Puede, pero debe anular __new__ que se llama implícitamente antes de __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

¡Pero d será solo un atributo independiente!

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