super() 사용 소개
클래스 상속에서 메서드를 재정의하면 해당 메서드가 상위 클래스의 동일한 이름의 메서드를 재정의하지만 때로는 다음과 같은 기능을 구현하기를 바랍니다. 동시에 부모 클래스의 메소드를 호출해야 합니다. 이는 super를 사용하여 달성할 수 있습니다.
class Animal(object): def __init__(self, name): self.name = name def greet(self): print 'Hello, I am %s.' % self.name class Dog(Animal): def greet(self): super(Dog, self).greet() # Python3 可使用 super().greet() print 'WangWang...'
위에서 Animal은 부모 클래스인 Dog는 하위 클래스이므로 Dog 클래스에서 반복합니다. Greeting 메서드는 부모 클래스의 기능을 동시에 구현하기 위해 부모 클래스의 메서드도 호출합니다. :
>>> dog = Dog('dog') >>> dog.greet() Hello, I am dog. WangWang..
super의 가장 일반적인 용도 중 하나는 하위 클래스에 있다고 할 수 있습니다. 다음과 같이 상위 클래스의 초기화 메서드를 호출합니다.
class Base(object): def __init__(self, a, b): self.a = a self.b = b class A(Base): def __init__(self, a, b, c): super(A, self).__init__(a, b) # Python3 可使用 super().__init__(a, b) self.c = c
super( )
위의 사용법을 읽고 나면 super의 사용법이 매우 간단하다는 것을 느낄 수 있습니다. 상위 클래스를 가져와서 상위 클래스의 메서드를 호출하는 것 외에는 아무것도 아닙니다. 실제로 위의 경우에는 super가 획득한 클래스가 우연히 부모 클래스가 되지만, 다른 경우에는 Super가 실제로 부모 클래스와 실질적인 관계가 없는 것은 아닙니다.
다중 상속과 관련된 좀 더 복잡한 예를 살펴보겠습니다.
class Base(object): def __init__(self): print "enter Base" print "leave Base" class A(Base): def __init__(self): print "enter A" super(A, self).__init__() print "leave A" class B(Base): def __init__(self): print "enter B" super(B, self).__init__() print "leave B" class C(A, B): def __init__(self): print "enter C" super(C, self).__init__() print "leave C"
그 중 Base가 상위 클래스이고 A와 B가 Base를 상속하고, C는 A, B를 상속하며, 이들의 상속 관계는 다음과 같습니다.
Base / \ / \ A B \ / \ / C
이제 사용법을 살펴보겠습니다.
>>> c = C() enter C enter A enter B enter Base leave Base leave B leave A leave C
super가 " call the method of the parent class"라고 입력하면 enter A의 다음 문장이 왜 enter Base가 아니고 enter B인지 궁금할 것입니다. 그 이유는 super가 부모 클래스와 실질적인 관계가 없기 때문입니다. 이제 super가 어떻게 작동하는지 알아 보겠습니다.
MRO 목록
실제로 정의한 각 클래스에 대해 Python은 클래스 상속 순서를 나타내는 MRO(메서드 해결 순서) 목록을 계산합니다. 다음 메서드를 사용할 수 있습니다. 특정 클래스의 MRO 목록을 얻으려면:
>>> C.mro() # or C.__mro__ or C().__class__.mro() [__main__.C, __main__.A, __main__.B, __main__.Base, object]
이 MRO 목록의 순서는 어떻게 결정됩니까? 이는 C3 선형화 알고리즘을 통해 구현됩니다. 일반적으로 클래스의 MRO 목록은 모든 상위 클래스의 MRO 목록을 병합하고 다음 세 가지 원칙을 따르는 것입니다.
하위 클래스는 항상 상위 클래스보다 앞에 있습니다. 🎜>
부모 클래스가 여러 개인 경우 목록의 순서에 따라 검사합니다.다음 클래스에 합법적인 선택이 2개인 경우 첫 번째 부모 클래스가 선택됩니다.super 원칙super는 다음과 같이 작동합니다.def super(cls, inst): mro = inst.__class__.mro() return mro[mro.index(cls) + 1]
super(C, self).__init__()
[__main__.C, __main__.A, __main__.B, __main__.Base, object]
super(A, self).__init__()