단일 상속에서 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는 상위 클래스가 아니지만 상속 순서에서 다음 클래스입니다
다중 상속의 경우 상속 순서가 관련됩니다. 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 '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
supder는 상위 클래스와 관련이 없으므로 실행 순서는 A —> B—>—>Base
실행 프로세스는 다음과 같습니다. childC()를 초기화할 때 먼저 childA 생성자에서 super(childA, self).__init__()를 호출하고, super(childA, self)는 상속 시퀀스에서 childA 다음에 반환됩니다. 현재 클래스 A 클래스 childB; 그런 다음 childB().__init()__를 실행하고 이 순서대로 계속합니다.
다중 상속에서 childA()의 super(childA, self).__init__()를 Base.__init__(self)로 바꾸면 실행 중에 childA를 상속한 후 Base 클래스와 childB로 직접 점프합니다. 건너뛰었습니다:
enter A Base create leave A (<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
super() 메소드에서 볼 수 있듯이 super()의 첫 번째 매개변수는 상속 체인에 있는 모든 클래스의 이름이 될 수 있습니다.
그 자체라면 다음 클래스를 차례로 상속받습니다.
상속 체인의 이전 클래스인 경우 무한 반복됩니다.
상속 체인의 이후 클래스인 경우 상속 체인 요약 자체와 들어오는 클래스 사이의 클래스는 무시됩니다.
예를 들어, childA()에서 super가 super(childC, self).init()로 변경되면 프로그램은 무한히 반복됩니다.
예:
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, 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 'Base create' class childA(Base): def __init__(self): print 'enter A ' Base.__init__(self) print 'leave A' 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 'Base create' class childA(Base): def __init__(self): print 'enter A ' super(childA, self).__init__() print 'leave A' class childB(childA, Base): def __init__(self): super(childB, self).__init__() b = childB() print b.__class__.mro() enter A Base create leave A [<class '__main__.childB'>, <class '__main__.childA'>, <class '__main__.Base'>, <type 'object'>]
위는 편집자가 소개한 Python 클래스의 super()와 __init__()의 차이점입니다. 궁금한 사항이 있으면 메시지를 남겨주시면 편집자가 답변해 드리겠습니다. 당신은 시간에. 또한 Script House 웹사이트를 지원해 주시는 모든 분들께 감사의 말씀을 전하고 싶습니다!