다음을 사용 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를 이해하고 싶습니다.
추신 : Joachim은 새로운 스타일의 인스턴스가되는 것과는 같지 않다고 지적했습니다 object
. 나는 그 반대를 여러 번 읽었으므로 혼란 스럽다 (인스턴스 테스트를 기반으로 한 새로운 스타일의 클래스 인스턴스 테스트 object
예 : https : //.com/revisions/2655651/3 ).
답변
보통은 ” 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())
은 IS instance
유형, 않습니다 상속 object
. 기본적으로 구식 클래스는 유형의 객체를 생성합니다 instance
(신규 스타일 클래스는 유형이 클래스 자체 인 객체를 생성 함). 인스턴스 이유는 아마도 OldStyle()
이다 object
: 그것 type()
에서 상속 object
(동급는 않는다는 사실 없습니다 에서 상속 object
계산하지 않습니다는 : 이전 스타일의 클래스는 단지 형식의 새로운 객체를 생성 instance
). 부분 참조 :https://stackoverflow.com/a/9699961/42973 .
추신 : 새로운 스타일의 클래스와 구식 클래스의 차이점은 다음과 같이 볼 수도 있습니다.
>>> 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
(구식 클래스는 유형 이 아니므로 인스턴스 유형이 될 수 없습니다).
답변
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 = []
답변
을 사용할 수도 있습니다 class TextParser(HTMLParser, object):
. 이 만드는 새로운 스타일의 클래스를, 그리고 사용할 수 있습니다.TextParser
super()
답변
문제는 조상 이 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
답변
당신은 (버전 2.6) 상속 트리를 보면, HTMLParser
상속에서 SGMLParser
상속에서 어느 ParserBase
한 하지 않습니다 에서 상속을 object
. 즉, HTMLParser는 구식 클래스입니다.
로 확인에 대해 isinstance
ipython에서 빠른 테스트를 수행했습니다.
[1]에서 : 클래스 A : ...: 통과하다 ... : [2]에서 : isinstance (A, object) 아웃 [2] : 맞음
클래스가 구식 클래스 인 경우에도 여전히의 인스턴스입니다 object
.
답변
올바른 방법은 ‘object’에서 상속하지 않는 구식 클래스에서 다음과 같습니다.
class A:
def foo(self):
return "Hi there"
class B(A):
def foo(self, name):
return A.foo(self) + name
답변
FWIW 그리고 나는 파이썬 전문가가 아니지만 이것으로 끝났다.
>>> 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
(...)
필요에 따라 구문 분석 결과를 다시 얻었습니다.