Python super ()는 TypeError를 발생시킵니다.


109

Python 2.5에서 다음 코드는 a를 발생시킵니다 TypeError.

>>> class X:
      def a(self):
        print "a"

>>> class Y(X):
      def a(self):
        super(Y,self).a()
        print "b"

>>> c = Y()
>>> c.a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in a
TypeError: super() argument 1 must be type, not classobj

나는를 교체 할 경우 class Xclass X(object), 그것은 작동합니다. 이것에 대한 설명은 무엇입니까?


3
귀하의 "그러나 나는 클래스 X를 클래스 X (객체)로 대체"하여 내 문제를 해결했습니다! 고맙습니다
AliBZ 2013 년

답변:


132

그 이유는 2.x 시리즈에서 다음과 같은 확장을 의미하는 새로운 스타일의 클래스super() 에서만 작동하기 때문입니다 .object

>>> class X(object):
        def a(self):
            print 'a'

>>> class Y(X):
        def a(self):
            super(Y, self).a()
            print 'b'

>>> c = Y()
>>> c.a()
a
b

4
어떤 파이썬 버전에서 이것이 기본 동작이 되었습니까?
Geo

6
2.2는 새로운 스타일의 클래스가 도입되었을 때였고, 3.0이 기본값이되었습니다.
Cody Brocious

7
@tsunami 만약 당신이 슈퍼 클래스에 가고 싶다면 "Xa (self)"를하세요
James Brady

당신이 나를 오해 한 것 같아요. 삼부작. 나는 내가 3.0 미만의 파이썬 버전을 사용하고 있었다는 것을 기억한다. 그리고 나는 내 클래스가 Object로부터 상속받는다고 구체적으로 말하지 않았고, super에 대한 호출이 작동했다. 아마도 2.6의 기본 동작일까요? 그냥 :) 말
지오

Alabaster, 그럴 필요가 없습니다. 새로운 스타일의 수업은 슈퍼뿐만 아니라 많은 이점이 있습니다. 구식 방식을 홍보해서는 안됩니다.
Cody Brocious

14

또한 꼭 필요한 경우가 아니면 super ()를 사용하지 마십시오. 의심 할 수있는 새로운 스타일의 클래스와 관련된 일반적인 목적의 "올바른 일"이 아닙니다.

다중 상속을 예상하고 원하는 경우가있을 수 있지만 MRO에 대한 자세한 정보를 알 때까지는 그대로두고 다음을 준수하는 것이 가장 좋습니다.

 X.a(self)

2
6 개월 동안 Python / Django에서 super를 "일반적으로해야 할 일"로 사용했기 때문에 그게 맞습니까?
philgo20 2010

1
글쎄, 그것은 그 자체로 단일 상속에 대해 당신을 해치지 않지만 (약간 더 느리다는 점을 제외하고), 그 자체로 아무것도 얻지 못합니다. __init__명확하고 합리적인 방식으로 인수를 전달 하기 위해 곱셈 상속 (특히 ) 이 필요한 메서드를 설계해야합니다 . 그렇지 않으면 누군가가 클래스를 사용하여 곱셈 상속을 시도 할 때 TypeErrors 또는 더 나쁜 디버깅 문제가 발생합니다. 이러한 방식으로 MI를 지원하도록 설계하지 않았다면 (매우 까다로운) super방법이 MI에 안전하다는 의미를 피하는 것이 좋습니다 .
bobince

3

위의 답변 중 어느 것도 명확하게 언급하지 않은 경우. 부모 클래스는 "객체"에서 상속해야하며, 이는 본질적으로 새로운 스타일 클래스로 바뀝니다.

# python 3.x:
class ClassName(object): # This is a new style class
    pass

class ClassName: # This is also a new style class ( implicit inheritance from object )
    pass

# Python 2.x:
class ClassName(object): # This is a new style class
    pass

class ClassName:         # This is a old style class
    pass

죄송합니다. Python 3.x에서는 두 번째 예제 (암시 적 상속)가 언급 된 문제의 맥락에서 실제로 작동하지 않습니다.
sophros

1

다양한 Xa () 메서드를 시도했습니다. 그러나 그들은 a ()를 수행하기 위해 X의 인스턴스가 필요한 것처럼 보이므로 적어도 내가 만난 응용 프로그램에 대해서는 이전 답변보다 더 완전한 것처럼 보이는 X (). a (self)를 수행했습니다. 불필요한 건설과 파괴가 있기 때문에 문제를 처리하는 좋은 방법은 아닌 것 같지만 잘 작동합니다.

내 특정 응용 프로그램은 Python의 cmd.Cmd 모듈이었는데, 어떤 이유로 든 NewStyle 객체가 아닌 것 같습니다.

최종 결과:

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