El siguiente uso de super()plantea un error de tipo: ¿por qué?
>>> from HTMLParser import HTMLParser
>>> class TextParser(HTMLParser):
... def __init__(self):
... super(TextParser, self).__init__()
... self.all_data = []
...
>>> TextParser()
(...)
TypeError: must be type, not classobj
Hay una pregunta similar en StackOverflow: Python super () plantea TypeError , donde el error se explica por el hecho de que la clase de usuario no es una clase de estilo nuevo. Sin embargo, la clase anterior es una clase de nuevo estilo, ya que hereda de object:
>>> isinstance(HTMLParser(), object)
True
¿Qué me estoy perdiendo? ¿Cómo puedo usar super()aquí?
Usar en HTMLParser.__init__(self)lugar de super(TextParser, self).__init__()funcionaría, pero me gustaría entender el TypeError.
PD: Joachim señaló que ser una instancia de clase de estilo nuevo no es equivalente a ser un object. Leí lo contrario muchas veces, de ahí mi confusión (ejemplo de prueba de instancia de clase de nuevo estilo basada en objectprueba de instancia: https://stackoverflow.com/revisions/2655651/3 ).
fuente

super.__doc__no menciona nada sobre el estilo antiguo frente al nuevo!super()solo funciona para clases (y objetos) de estilo nuevo se menciona en el documento HTML ( docs.python.org/library/functions.html#super ).Respuestas:
Muy bien, es lo habitual "
super()no se puede usar con una clase de estilo antiguo".Sin embargo, el punto importante es que la prueba correcta para "¿es esta una instancia de nuevo estilo (es decir, un objeto)?" es
y no (como en la pregunta):
Para las clases , la prueba correcta de "es una clase de estilo nuevo" es:
El punto crucial es que con las clases de estilo antiguo, la clase de una instancia y su tipo son distintos. En este caso,
OldStyle().__class__esOldStyleque no hereda deobject, mientras quetype(OldStyle())es elinstancetipo, que no heredan deobject. Básicamente, una clase de estilo antiguo solo crea objetos de tipoinstance(mientras que una clase de estilo nuevo crea objetos cuyo tipo es la clase misma). Esta es probablemente la razón por la cual la instanciaOldStyle()esobject:type()hereda deobject(el hecho de que su clase no herede deobjectno cuenta: las clases de estilo antiguo simplemente construyen nuevos objetos de tipoinstance). Referencia parcial:https://stackoverflow.com/a/9699961/42973 .PD: La diferencia entre una clase de estilo nuevo y una de estilo antiguo también se puede ver con:
(las clases de estilo antiguo no son tipos, por lo que no pueden ser el tipo de sus instancias).
fuente
(Oldstyle().__class__ is Oldstyle)esTrueOldStyle().__class__es mostrar cómo probar si un objeto (OldStyle()) proviene de una clase de estilo antiguo. Con solo las clases de estilo nuevo en mente, uno podría verse tentado a hacer la pruebaisinstance(OldStyle(), object).object, por lo que te atornilla por proxy.super () solo se puede usar en las clases de estilo nuevo, lo que significa que la clase raíz debe heredar de la clase 'objeto'.
Por ejemplo, la clase superior debe ser así:
no
Entonces, la solución es llamar directamente al método init del padre , de esta manera:
fuente
selfparámetros en laHTMLParser.__init__()llamada.También puedes usar
class TextParser(HTMLParser, object):. Esto haceTextParseruna nueva clase de estilo , ysuper()se puede usar.fuente
El problema es que
supernecesitaobjectun antepasado:En un examen más detallado, uno encuentra:
Pero:
Entonces, la solución a su problema sería heredar del objeto y de HTMLParser. Pero asegúrese de que el objeto venga último en las clases MRO:
fuente
type(myclass), lo que importa es simyclassheredar del objeto (es decir, siisinstance(myclass, object)es verdadero, es falso).Si observa el árbol de herencia (en la versión 2.6),
HTMLParserhereda de loSGMLParserque hereda deParserBaselo que no heredaobject. Es decir, HTMLParser es una clase de estilo antiguo.Sobre su verificación con
isinstance, hice una prueba rápida en ipython:Incluso si una clase es de estilo antiguo, sigue siendo una instancia de
object.fuente
isinstance(A(), object), noisinstance(A, object), ¿no? Con este último, está probando si la claseAes unaobject, mientras que la pregunta es si las instancias deAson unaobject, ¿verdad?issubclass(HTMLParser, object), que devuelve False.la forma correcta de hacerlo será la siguiente en las clases de estilo antiguo que no hereda de 'objeto'
fuente
Aque almacena un estado.FWIW y aunque no soy un gurú de Python, me las arreglé con esto
Acabo de recibir los resultados del análisis según sea necesario.
fuente