262

class A:
 def __init__(self):
   print "world"

class B(A):
 def __init__(self):
   print "hello"

B()
hello

슈퍼 생성자로 작업 한 다른 모든 언어에서는 암시 적으로 호출됩니다. 파이썬에서 어떻게 호출합니까? 나는 기대할 것이다.super(self)그러나 이것은 효과가 없습니다.


6 답변


270

super()부모와 같은 객체를 반환합니다.새로운 스타일의 수업:

class A(object):
    def __init__(self):
        print "world"

class B(A):
    def __init__(self):
        print "hello"
        super(B, self).__init__()

B()


  • 왜 호기심을하는거야?super(B,self)B와 자기가 모두 언급 될 것을 요구 하는가? 이 중복되지 않습니까? B 자체에 대한 참조가 이미 포함되어 있지 않아도됩니까? - Mike
  • 아니, 왜냐하면self실제로는C,의B. - Ignacio Vazquez-Abrams
  • @Luc : 클래스가 잘못 선언 되었기 때문입니다. 내 대답을 보라. - Ignacio Vazquez-Abrams
  • 에 관해서는문서super(), 당신은 쓸 수 있어야합니다.super().__init__()너의 주장은 아니야. - JojOatXGME
  • @JojOatXGME : 3.x에서 예. 2.x는 여전히 인수가 필요합니다. - Ignacio Vazquez-Abrams

160

다른 대답에 따라 수퍼 클래스 메서드 (생성자 포함)를 호출하는 여러 가지 방법이 있지만 Python-3.x에서는 프로세스가 단순화되었습니다.

Python-2.x

class A(object):
 def __init__(self):
   print "world"

class B(A):
 def __init__(self):
   print "hello"
   super(B, self).__init__()

Python-3.x

class A(object):
 def __init__(self):
   print("world")

class B(A):
 def __init__(self):
   print("hello")
   super().__init__()

super()이제는super(<containing classname>, self)~만큼문서.


50

Python 2.x 구식 클래스에서는 다음과 같이됩니다.

class A: 
 def __init__(self): 
   print "world" 

class B(A): 
 def __init__(self): 
   print "hello" 
   A.__init__(self)


  • 새로운 스타일 수업에는 효과가 없습니까? - kdbanman
  • @kdbanman : 이것은 새로운 스타일의 클래스에서 작동하지만 새로운 스타일의 클래스를 사용하는 이유 중 하나는 이런 식으로 할 필요가 없다는 것입니다. 당신이 사용할 수있는super당신이 상속 한 클래스의 이름을 직접 지정할 필요는 없습니다. - Gabe

32

한 가지 방법은 A의 생성자를 호출하고 전달하는 것입니다.self인수로서, 이렇게 :

class B(A):
    def __init__(self):
        A.__init__(self)
        print "hello"

이 스타일의 장점은 매우 분명합니다. A의 생성자를 호출합니다. 단점은 공유 기본 클래스의 생성자를 두 번 호출 할 수 있기 때문에 다이아몬드 모양의 상속을 잘 처리하지 못한다는 것입니다.

다른 방법으로 super ()를 사용하는 방법도 있습니다. 단일 상속의 경우 기본적으로 부모 생성자를 호출하는 것과 동일한 작업을 수행합니다.

그러나 super ()는 상당히 복잡하고 여러 상속 상황에서 카운터 직관적 인 경우가 있습니다. 더하기 측면에서 super ()는 다이아몬드 모양의 상속을 처리하는 데 사용할 수 있습니다. super ()가하는 일의 핵심을 알고 싶다면, super ()가 어떻게 작동하는지에 대한 가장 좋은 설명은이리(필자는 그 기사의 의견을 반드시지지하지는 않지만).


  • 변수로 (자기를 무시한) 변수를 인수로 사용하지 않으면 A의 생성자를 호출 할 필요가 있습니까? 코드가 제대로 작동 함을 의미합니다.A.__init__(self)선. - Red Floyd

2

이전 답변을 확장 한 다음 수식을 사용합니다.

class A(object):
 def __init__(self):
   print "world"

class B(A):
 def __init__(self):
   print "hello"
   super(self.__class__, self).__init__()

B()

이렇게하면 호출 할 때 클래스 이름을 반복하지 않아도됩니다.감독자. 많은 수의 클래스를 코딩하고 있으며 클래스 이름과는 별도로 생성자 메서드에서 코드를 작성하려는 경우 유용 할 수 있습니다.


  • 그러나 확장하기로 결정하면 무한 재귀가 발생합니다.BC, 및self.__class__~에 중점을 두다C(B)대신에B(A), 그래서super(self.__class__, self)다시 가리킨다.B대신에A. - dened
  • 이렇게하면 하위 클래스를 만들 때 무한 재귀 오류가 발생합니다.B. 해야 할 것아니용도self.__class__또는type(self), 명시 적 클래스에서 전달하거나 (B여기) 또는 파이썬 3에서super()인수없이. - Martijn Pieters

2

짧은 답변

super(DerivedClass, self).__init__()

긴 답변

무엇을 하는가?super()해야 할 것?

그것은 지정된 클래스 이름을 취하고, 기본 클래스를 찾고 (파이썬은 다중 상속을 허용 함) 메소드를 찾습니다 (__init__이 경우) 각각 왼쪽에서 오른쪽으로. 사용할 수있는 메소드를 찾자 마자 호출하여 메소드를 종료합니다.

모든 기본 클래스의 init을 호출하려면 어떻게해야합니까?

위에서 기본 클래스가 하나만있는 경우 작동합니다. 하지만 파이썬은 다중 상속을 허용하고 모든 기본 클래스가 제대로 초기화되도록 할 수 있습니다. 이를 수행하기 위해 각 기본 클래스에서 init을 호출해야합니다.

class Base1:
  def __init__():
    super(Base1, self).__init__()

class Base2:
  def __init__():
    super(Base2, self).__init__()

class Derived(Base1, Base2):
  def __init__():
    super(Derived, self).__init__()

수퍼에 대해 init을 호출하는 것을 잊으면 어떻게 될까요?

그만큼__init__기본 클래스가 호출되지 않습니다. C ++ 및 Java와 같은 암시 적 생성자 호출은 없습니다.

연결된 질문


관련된 질문

최근 질문