Python 클래스의 super()와 __init__()의 차이점에 대한 설명

高洛峰
풀어 주다: 2017-03-16 16:08:29
원래의
1376명이 탐색했습니다.

싱글 을 상속하는 경우 super()와 init()에 의해 구현된 함수는 유사합니다.

class Base(object):
    def init(self):
        print 'Base create'
class childA(Base):
    def init(self):
        print 'creat A ',
        Base.init(self)
class childB(Base):
    def init(self):
        print 'creat B ',
        super(childB, self).init()
base = Base()
a = childA()
b = childB()
로그인 후 복사

출력 결과:

Base create
creat A  Base create
creat B  Base create
로그인 후 복사

차이점은 super() 상속을 사용할 때 기본 클래스를 명시적으로 참조할 필요가 없다는 것입니다.


super()는 새로운 스타일 클래스에서만 사용할 수 있습니다.


기본 클래스를 다음으로 변경하세요. 즉,

class Base():
    def init(self):
        print 'Base create'
로그인 후 복사

가 실행되면 b:

super(childB, self).init()
TypeError: must be type, not classobj
로그인 후 복사


를 초기화할 때 오류가 보고됩니다.

super는 상위 클래스가 아니지만


의 다음 클래스는 다중 상속 중 상속 순서를 포함합니다. 부모 클래스가 아닌 상속 순서의 다음 클래스. 이 함수와 유사합니다.

def super(class_name, self):
    mro = self.class.mro()
    return mro[mro.index(class_name) + 1]
로그인 후 복사

mro()는 클래스의 상속 순서를 가져오는 데 사용됩니다. 예:

class Base(object):
    def init(self):
        print 'Base create'
class childA(Base):
    def init(self):
        print 'enter A '
        # Base.init(self)
        super(childA, self).init()
        print 'leave A'
class childB(Base):
    def init(self):
        print 'enter B '
        # Base.init(self)
        super(childB, self).init()
        print 'leave B'
class childC(childA, childB):
    pass
c = childC()
print c.class.mro
로그인 후 복사

출력 결과는 다음과 같습니다.

enter A 
enter B 
Base create
leave B
leave A
(<class &#39;main.childC&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.childB&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>)
로그인 후 복사

supder는 상위 클래스와 관련이 없으므로 실행 순서는 A —>B—>—>Base입니다.


실행 프로세스는 다음과 같습니다. childC()를 초기화할 때 먼저 super(childA, self).init()를 호출하고 super(childA, self)가 반환됩니다. 현재 클래스의 상속 순서에 따라 childB 클래스가 childB().init()를 실행하고 시퀀스가 ​​계속됩니다.


다중 상속에서는 childA()의 super(childA, self).init()를 Base._init_(self)로 대체하면 실행 중 childA를 상속받은 후 , childB를 건너뛰고 기본 클래스로 직접 점프합니다.

enter A 
Base create
leave A
(<class &#39;main.childC&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.childB&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>)
로그인 후 복사

super() 메서드에서 볼 수 있듯이 super()의 첫 번째 매개 변수는 상속 체인 이름의 모든 클래스일 수 있습니다. 🎜>

그 자체라면 다음 클래스를 차례로 상속합니다.

체인 클래스는 무한히
재귀

됩니다.

상속 체인에서 이후 클래스인 경우 상속 체인 요약 자체와 들어오는 클래스는 무시됩니다.

예를 들어 childA()의 super가 super(childC, self).init()로 변경되면 프로그램이 반복됩니다. 무한히. 예:

  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
  File "test.py", line 12, in init
    super(childC, self).init()
RuntimeError: maximum recursion depth exceeded while calling a Python object
로그인 후 복사

super()는

에 대한 반복 호출을 피할 수 있습니다. childA가 Base를 기반으로 하는 경우 childB childA 및 Base 를 상속합니다. childB가 Base의 init() 메서드를 호출해야 하는 경우 init()가 두 번 실행됩니다.

class Base(object):
    def init(self):
        print &#39;Base create&#39;
class childA(Base):
    def init(self):
        print &#39;enter A &#39;
        Base.init(self)
        print &#39;leave A&#39;
class childB(childA, Base):
    def init(self):
        childA.init(self)
        Base.init(self)
b = childB()
로그인 후 복사

Base의 init() 메서드가 두 번 실행됩니다.

enter A 
Base create
leave A
Base create
로그인 후 복사

super()를 사용하면 반복 호출을 피할 수 있습니다

class Base(object):
    def init(self):
        print &#39;Base create&#39;
class childA(Base):
    def init(self):
        print &#39;enter A &#39;
        super(childA, self).init()
        print &#39;leave A&#39;
class childB(childA, Base):
    def init(self):
        super(childB, self).init()
b = childB()
print b.class.mro()
enter A 
Base create
leave A
[<class &#39;main.childB&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>]
로그인 후 복사

위 내용은 Python 클래스의 super()와 __init__()의 차이점에 대한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿