super ()가 오류와 함께 실패 : TypeError 부모가 객체를 상속하지 않으면 "인수 1은 classobj가 아니라 형식이어야합니다"


196

알아낼 수없는 오류가 발생합니다. 샘플 코드에 어떤 문제가 있습니까?

class B:
    def meth(self, arg):
        print arg

class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)

print C().meth(1)

'super'내장 메소드의 도움으로 샘플 테스트 코드를 얻었습니다.

오류는 다음과 같습니다.

Traceback (most recent call last):
  File "./test.py", line 10, in ?
    print C().meth(1)
  File "./test.py", line 8, in meth
    super(C, self).meth(arg)
TypeError: super() argument 1 must be type, not classobj

참고로, 다음은 파이썬 자체의 도움 (슈퍼)입니다.

Help on class super in module __builtin__:

class super(object)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
 |  class C(B):
 |      def meth(self, arg):
 |          super(C, self).meth(arg)
 |


3
메스 ?? 프로그래밍 용어입니까, 아니면 ... 아십니까? 명확히하십시오.
Cplusplusplus

3
@Cplusplusplus : 아마도 Method ;-)의 약자
ShadowFlame

답변:


333

문제는 클래스 B가 "새 스타일"클래스로 선언되지 않았다는 것입니다. 다음과 같이 변경하십시오.

class B(object):

작동합니다.

super()모든 서브 클래스 / 슈퍼 클래스는 새로운 스타일의 클래스에서만 작동합니다. (object)클래스 정의에 항상 새 스타일 클래스가되도록 입력하는 습관을들이는 것이 좋습니다 .

구식 클래스 ( "클래식"클래스라고도 함)는 항상 유형입니다 classobj. 새 스타일 클래스는 유형 type입니다. 이것이 바로 오류 메시지가 나타난 이유입니다.

TypeError: super() argument 1 must be type, not classobj

이것을 직접보십시오 :

class OldStyle:
    pass

class NewStyle(object):
    pass

print type(OldStyle)  # prints: <type 'classobj'>

print type(NewStyle) # prints <type 'type'>

Python 3.x에서 모든 클래스는 새로운 스타일입니다. 여전히 구식 클래스의 구문을 사용할 수 있지만 새로운 스타일의 클래스를 얻게됩니다. 따라서 Python 3.x에서는이 문제가 없습니다.


흥미롭게도 Py27에서는 실행되지만 Py33에서는 실행되지 않는 비슷한 오류 (TypeError : classobj가 아닌 type이어야 함)를 발생시키는 bottle.py ( bottlepy.org )를 실행하는이 정확한 문제를 발견했습니다 .
bootload

Python 3.x에는 더 이상 "이전 스타일"클래스가 없습니다. "old-style"선언을 사용하는 코드는 여전히 "new-style"클래스를 선언하므로이 오류는 Python 3.x에서 발생할 수 없습니다.
steveha

1
클래스 B를 편집 할 수없는 경우 클래스 A를 편집하여 사용하지 마십시오 super(). 클래스 A는 "구식"클래스와 함께 작동하도록해야하며,이를 수행하는 가장 좋은 방법은 클래스 A 자체를 "구식"클래스로 만드는 것입니다. 물론 파이썬 3.x에서 실행되도록 전체 프로그램을 업그레이드하는 것이 좋습니다. 그래서 모든 클래스가 당신이 무엇을하든 새로운 스타일이 될 것입니다. 해당 옵션을 사용할 수있는 것이 가장 좋습니다.
steveha

같은 문제가 있지만 기본 클래스는 다음과 같이 선언 class B(object):됩니다. @mock.patch('module.B', autospec=B)테스트 사례 직전 에 사용했기 때문에이 오류가 발생합니다 . 이 문제를 해결하는 방법에 대한 생각이 있습니까?
MikeyE

154

또한 클래스 B를 변경할 수없는 경우 다중 상속을 사용하여 오류를 수정할 수 있습니다.

class B:
    def meth(self, arg):
        print arg

class C(B, object):
    def meth(self, arg):
        super(C, self).meth(arg)

print C().meth(1)

16
나는 의견을 남기는 것을 도울 수 없었습니다.이 의견은 '표준'답변으로 받아 들여 져야합니다.
workplaylifecycle

9
미래의 구글 직원들에게 파이썬 2.6에 갇혀 : 이것은 아마도 당신이 원하는 대답입니다! 기본 클래스를 변경할 수없는 경우 (예 : 표준 라이브러리 클래스를 서브 클래 싱하는 경우) 자신의 클래스로 변경하면 super ()가 수정됩니다.
coredumperror

그것은 나에게 잘 작동했습니다. 누군가 어떻게 작동하는지 설명 할 수 있습니까?
subro

@subro, 이것은 클래스를 "새로운 스타일"클래스 (클래스 객체가 유형 인 type클래스)로 만들면서 "구식"클래스 (클래스 객체가 유형 인 클래스)를 서브 클래 싱합니다 classobj. super()새로운 스타일의 클래스에서는 작동하지만 이전 스타일의 클래스에서는 작동하지 않습니다.
MarSoft

완벽한 답변!
Tom

18

파이썬 버전이 3.X라면 괜찮습니다.

파이썬 버전이 2.X라고 생각합니다.이 코드를 추가하면 슈퍼가 작동합니다.

__metaclass__ = type

그래서 코드는

__metaclass__ = type
class B:
    def meth(self, arg):
        print arg
class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)
print C().meth(1)

4

파이썬 2.7을 사용할 때 게시 된 문제에 직면했습니다. 파이썬 3.4에서 매우 잘 작동합니다.

파이썬 2.7에서 작동하게하려면 __metaclass__ = type프로그램 상단에 속성을 추가하고 작동했습니다.

__metaclass__ : 구식 수업과 새로운 스타일 수업에서 쉽게 전환 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.