super () вызывает "TypeError: должен быть типом, а не classobj" для класса нового стиля
134065 просмотра
7 ответа
Следующее использование super()
вызывает TypeError: почему?
>>> from HTMLParser import HTMLParser
>>> class TextParser(HTMLParser):
... def __init__(self):
... super(TextParser, self).__init__()
... self.all_data = []
...
>>> TextParser()
(...)
TypeError: must be type, not classobj
Есть аналогичный вопрос о StackOverflow: Python super () вызывает TypeError , где ошибка объясняется тем фактом, что пользовательский класс не является классом нового стиля. Однако вышеприведенный класс является классом нового стиля, поскольку он наследуется от object
:
>>> isinstance(HTMLParser(), object)
True
Чего мне не хватает? Как я могу использовать super()
здесь?
Использование HTMLParser.__init__(self)
вместо того, super(TextParser, self).__init__()
чтобы работать, но я хотел бы понять TypeError.
PS: Йоахим отметил, что быть экземпляром класса нового стиля не эквивалентно тому, чтобы быть object
. Я много раз читал противоположное, отсюда моя путаница (пример теста экземпляра класса нового стиля на основе object
теста экземпляра: https://stackoverflow.com/revisions/2655651/3 ).
Ответы (7)
244 плюса
Хорошо, это обычно " super()
не может использоваться с классом старого стиля".
Тем не менее, важным моментом является то, что правильный тест для "это экземпляр нового стиля (то есть объект)?" является
>>> class OldStyle: pass
>>> instance = OldStyle()
>>> issubclass(instance.__class__, object)
False
а не (как в вопросе)
>>> isinstance(instance, object)
True
Для классов правильный тест «это новый класс»:
>>> issubclass(OldStyle, object) # OldStyle is not a new-style class
False
>>> issubclass(int, object) # int is a new-style class
True
Важный момент является то , что со старым стилем классов, класс экземпляра и его типа различны. Здесь OldStyle().__class__
есть OldStyle
, что не наследует object
, а type(OldStyle())
это instance
тип, который действительно наследует от object
. По сути, класс старого стиля просто создает объекты типа instance
(тогда как класс нового стиля создает объекты, типом которых является сам класс). Вероятно, поэтому экземпляр OldStyle()
является наследником object
: его type()
наследует object
(тот факт, что его класс не наследует от object
, не считается: классы старого стиля просто создают новые объекты типа instance
). Частичная ссылка:https://stackoverflow.com/a/9699961/42973 .
PS: Различие между классом нового стиля и классом старого стиля также можно увидеть с помощью:
>>> type(OldStyle) # OldStyle creates objects but is not itself a type
classobj
>>> isinstance(OldStyle, type)
False
>>> type(int) # A new-style class is a type
type
(классы старого стиля не являются типами, поэтому они не могут быть типом своих экземпляров).
Автор: Eric O Lebigot Размещён: 15.03.2012 12:31198 плюса
super () может использоваться только в классах нового стиля, что означает, что корневой класс должен наследоваться от класса 'object'.
Например, верхний класс должен быть таким:
class SomeClass(object):
def __init__(self):
....
не
class SomeClass():
def __init__(self):
....
Итак, решение заключается в том, чтобы вызвать родительский метод init напрямую, например, так:
class TextParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.all_data = []
Автор: Colin Su
Размещён: 14.03.2012 09:07
28 плюса
Вы также можете использовать class TextParser(HTMLParser, object):
. Это делает класс TextParser
в новом стиле и super()
может использоваться.
22 плюса
Проблема в том, что super
нуждается object
в качестве предка:
>>> class oldstyle:
... def __init__(self): self.os = True
>>> class myclass(oldstyle):
... def __init__(self): super(myclass, self).__init__()
>>> myclass()
TypeError: must be type, not classobj
При ближайшем рассмотрении можно найти:
>>> type(myclass)
classobj
Но:
>>> class newstyle(object): pass
>>> type(newstyle)
type
Таким образом, решением вашей проблемы будет наследование от объекта, а также от HTMLParser. Но убедитесь, что объект идет последним в классах MRO:
>>> class myclass(oldstyle, object):
... def __init__(self): super(myclass, self).__init__()
>>> myclass().os
True
Автор: user2070206
Размещён: 17.10.2015 09:34
17 плюса
Если вы посмотрите на дерево наследования (в версии 2.6), HTMLParser
наследует, от SGMLParser
чего наследует, от ParserBase
которого не наследует object
. Т.е. HTMLParser - это класс в старом стиле.
Что isinstance
касается вашей проверки , я сделал быстрый тест в ipython:
В [1]: класс А: ...: проходят ...: В [2]: isinstance (A, объект) Out [2]: True
Даже если класс является классом старого стиля, он все еще является экземпляром object
.
5 плюса
правильный способ сделать это будет следующим в классах старого стиля, которые не наследуются от «объекта»
class A:
def foo(self):
return "Hi there"
class B(A):
def foo(self, name):
return A.foo(self) + name
Автор: Jacob Abraham
Размещён: 18.02.2014 12:30
0 плюса
FWIW и хотя я не гуру Python, я получил с этим
>>> class TextParser(HTMLParser):
... def handle_starttag(self, tag, attrs):
... if tag == "b":
... self.all_data.append("bold")
... else:
... self.all_data.append("other")
...
...
>>> p = TextParser()
>>> p.all_data = []
>>> p.feed(text)
>>> print p.all_data
(...)
Просто вернул мне результаты разбора по мере необходимости.
Автор: qwerty_so Размещён: 26.10.2018 03:03Вопросы из категории :
- python Обработка XML в Python
- python Как я могу использовать Python itertools.groupby ()?
- python Python: На какой ОС я работаю?
- python Как я могу создать непосредственно исполняемое кроссплатформенное приложение с графическим интерфейсом на Python?
- python Вызов функции модуля с использованием его имени (строки)
- superclass Можно ли вызывать методы подклассов на объекте суперкласса?
- superclass как наследовать конструктор от суперкласса до подкласса
- superclass Как вызвать супер-конструктор?
- superclass Когда реализовать интерфейс, а когда расширить суперкласс?
- superclass Частные члены в наследовании Java
- super Что «супер» делает в Python?
- super Понимание Python super () с помощью методов __init __ ()
- super Не нужно ли помещать super () в конструктор?
- super Что такое PECS (продюсер продлевает потребительский супер)?
- super Связывание дженериков с ключевым словом «super»
- typeerror Ruby on Rails TypeError
- typeerror Uncaught TypeError: Невозможно прочитать свойство 'значение' из неопределенного
- typeerror Ошибка типа: объект «builtin_function_or_method» не может быть подписан
- typeerror Uncaught Typeerror: не может прочитать свойство 'innerHTML' из null
- typeerror RuntimeWarning: компиляция версии 2.6 модуля 'lxml.etree' не соответствует версии исполнения 2.7