스택큐힙리스트

슈퍼()는 새로운 스타일 클래스에서 "TypeError: must be type, not classobj"를 발생시킵니다. 본문

카테고리 없음

슈퍼()는 새로운 스타일 클래스에서 "TypeError: must be type, not classobj"를 발생시킵니다.

스택큐힙리스트 2023. 4. 26. 15:32
반응형

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() raises TypeError. 이곳에서는 사용자 클래스가 새로운 스타일 클래스가 아니라는 사실 때문에 오류가 발생한다는 것이 설명되어 있습니다. 그러나 위의 클래스는 object에서 상속받아 새로운 스타일 클래스입니다.

>>> isinstance(HTMLParser(), object)

True

무엇이 빠졌을까요? 여기서 super()를 어떻게 사용할 수 있나요?

HTMLParser.__init__(self)을 사용하는 대신에 super(TextParser, self).__init__()을(를) 사용하는 것이 작동할 것이지만, 저는 TypeError를 이해하고 싶습니다.

PS: 조아킴은 새로운 스타일 클래스 인스턴스가 object 와 동일하다는 것은 아니라는 점을 지적했습니다. 나는 이와 반대되는 것을 여러 번 읽었기 때문에 혼란스러웠습니다 (새로운 스타일 클래스 인스턴스 테스트의 예시: https://stackoverflow.com/revisions/2655651/3 ).

답변 1

좋아요, 보통의 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입니다. 이는 @# does not c에서 상속하지 않습니다. 반면에 type(OldStyle()) is은 @# does not c에서 상속하는 instance 타입입니다. 기본적으로 옛 유형의 클래스는 instance 타입의 객체를 생성합니다(반면 새 유형의 클래스는 자체 클래스인 객체를 생성합니다). 이것이 아마도 is an #$!&&^^!$& 인스턴스가 @# does not c인 이유입니다: from #$!&&^^은 @# does not c에서 상속합니다(클래스가 @# does not c에서 상속되지 않는다는 사실은 중요하지 않습니다. 기존 유형의 클래스는 단순히 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

(구형 클래스는 유형이 아니므로 자신의 인스턴스 유형이 될 수 없습니다.)

답변 2

슈퍼() 함수는 새로운 스타일의 클래스에서 TypeError: must be type, not classobj 오류를 발생시킵니다. 이 오류는 클래스가 정의되는 방식에 따라 발생하는데, 구식 스타일로 정의된 클래스에서는 이 오류가 발생하지 않습니다.

클래스는 파이썬에서 객체를 정의하는 데 사용되며, 새로운 스타일의 클래스는 구식 스타일에 비해 몇 가지 이점을 제공합니다. 하지만 슈퍼() 함수를 사용할 때 주의해야 합니다. 슈퍼() 함수는 부모 클래스의 메소드를 호출하는 데 사용됩니다. 새로운 스타일의 클래스에서 이 함수를 사용할 때는 괄호 안에 자식 클래스와 self를 입력해야 합니다. 그러나 구식 스타일의 클래스에서는 괄호 안에 클래스 자체와 self만 입력하면 됩니다.

이 오류가 발생하는 이유는 새로운 스타일의 클래스에서는 클래스 객체가 타입(type)이고 classobj가 아니기 때문입니다. 따라서 슈퍼() 함수는 classobj 대신 슈퍼 클래스의 타입을 가져와야 합니다. 이 오류를 해결하려면 슈퍼() 함수를 호출할 때 object를 사용하면 됩니다.

이러한 이유로 super() 함수를 사용할 때는 새로운 스타일의 클래스에서 object를 사용하고 괄호 안에 자식 클래스와 self를 입력해야 합니다. 이러한 방법으로 오류를 방지할 수 있으며, 새로운 스타일의 클래스에서 슈퍼() 함수를 사용하여 부모 클래스의 메소드를 호출할 수 있습니다.

반응형
Comments