기본 (수퍼) 클래스를 어떻게 초기화합니까?


126

Python에서는 다음 코드가 있다고 가정합니다.

>>> class SuperClass(object):
    def __init__(self, x):
        self.x = x

>>> class SubClass(SuperClass):
    def __init__(self, y):
        self.y = y
        # how do I initialize the SuperClass __init__ here?

SuperClass __init__하위 클래스에서 어떻게 초기화 합니까? 나는 파이썬 튜토리얼을 따르고 있으며 그것을 다루지 않습니다. Google에서 검색했을 때 한 가지 이상의 방법을 찾았습니다. 이것을 처리하는 표준 방법은 무엇입니까?

답변:


147

Python (버전 3까지)은 "이전 스타일"및 새 스타일 클래스를 지원합니다. 새로운 스타일의 클래스는 object사용자가 사용하는 것에서 파생되며 super(), 예를 들어를 통해 기본 클래스를 호출합니다.

class X(object):
  def __init__(self, x):
    pass

  def doit(self, bar):
    pass

class Y(X):
  def __init__(self):
    super(Y, self).__init__(123)

  def doit(self, foo):
    return super(Y, self).doit(foo)

파이썬은 구식 및 신식 클래스에 대해 알고 있기 때문에 기본 메서드를 호출하는 여러 가지 방법이 있습니다. 이것이 여러 가지 방법을 찾은 이유입니다.

완전성을 위해 구식 클래스는 기본 클래스를 사용하여 명시 적으로 기본 메서드를 호출합니다.

def doit(self, foo):
  return X.doit(self, foo)

하지만 더 이상 구식을 사용하면 안되기 때문에 나는 이것에 대해 너무 신경 쓰지 않을 것입니다.

Python 3은 새로운 스타일의 클래스에 대해서만 알고 있습니다 (파생 여부에 관계없이 object).


38

양자 모두

SuperClass.__init__(self, x)

또는

super(SubClass,self).__init__( x )

작동합니다 (DRY 원칙을 더 많이 고수하기 때문에 두 번째 것을 선호합니다).

여기를 참조하십시오 : http://docs.python.org/reference/datamodel.html#basic-customization


8
잘못된. super는 새로운 스타일의 클래스에서만 작동하며 새로운 스타일의 클래스를 사용할 때 base를 호출하는 유일한 적절한 방법입니다. 또한 구식 구조를 사용하여 명시 적으로 'self'를 전달해야합니다.
Ivo van der Wijk

1
@Ivo-OP는 예제에서 새로운 스타일의 클래스를 제공했으며, 아무도 이전 스타일을 더 이상 사용해서는 안되므로 새로운 스타일과 이전 스타일의 차이에 대해 이야기 할 필요가 거의 없습니다. 내가 준 (Python 문서에 대한) 링크는 수퍼 클래스를 호출하는 하나 이상의 "적절한"방법이 있음을 시사합니다 __init__.
adamk


21

기본 (수퍼) 클래스를 어떻게 초기화합니까?

class SuperClass(object):
    def __init__(self, x):
        self.x = x

class SubClass(SuperClass):
    def __init__(self, y):
        self.y = y

super메서드 확인 순서에서 다음 메서드를 바인딩 된 메서드로 가져 오려면 개체를 사용하십시오 . Python 2에서는 self바인딩 된 __init__메서드 를 조회하려면 클래스 이름과 super를 전달해야합니다 .

 class SubClass(SuperClass):
      def __init__(self, y):
          super(SubClass, self).__init__('x')
          self.y = y

Python 3에는 인수를 super불필요하게 만드는 약간의 마술이 있습니다. 부수적으로 조금 더 빠르게 작동합니다.

 class SubClass(SuperClass):
      def __init__(self, y):
          super().__init__('x')
          self.y = y

아래와 같이 부모를 하드 코딩하면 협력 다중 상속을 사용할 수 없습니다.

 class SubClass(SuperClass):
      def __init__(self, y):
          SuperClass.__init__(self, 'x') # don't do this
          self.y = y

__init__반환 만None 있다는 점에 유의하십시오 -제자리에서 객체를 수정하기위한 것입니다.

어떤 것 __new__

인스턴스를 초기화하는 또 다른 방법이 있습니다. 이것은 파이썬에서 불변 유형의 서브 클래스를위한 유일한 방법입니다. 당신이 서브 클래스에 원하는 경우에 따라서는 필요한 것 str또는 tuple또는 다른 불변의 객체입니다.

암시 적 클래스 인수를 가져 오기 때문에 클래스 메서드라고 생각할 수 있습니다. 그러나 실제로는 staticmethod 입니다. 그래서 당신은 전화를 필요 __new__cls명시 적으로.

일반적으로에서 인스턴스를 반환 __new__하므로이 경우 기본 클래스에서도 기본을 __new__통해 호출해야합니다 super. 따라서 두 가지 방법을 모두 사용하는 경우 :

class SuperClass(object):
    def __new__(cls, x):
        return super(SuperClass, cls).__new__(cls)
    def __init__(self, x):
        self.x = x

class SubClass(object):
    def __new__(cls, y):
        return super(SubClass, cls).__new__(cls)

    def __init__(self, y):
        self.y = y
        super(SubClass, self).__init__('x')

Python 3 __new__은 정적 메서드로 인해 발생하는 수퍼 호출의 이상 함을 약간 회피 하지만 여전히 cls바인딩되지 않은 __new__메서드 로 전달해야합니다 .

class SuperClass(object):
    def __new__(cls, x):
        return super().__new__(cls)
    def __init__(self, x):
        self.x = x

class SubClass(object):
    def __new__(cls, y):
        return super().__new__(cls)
    def __init__(self, y):
        self.y = y
        super().__init__('x')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.