RoBoLoG

[Python] 클래스 만들 때 super().__init__() 사용하는 이유? + 부모 클래스가 2개 이상인 경우 본문

Study/Python

[Python] 클래스 만들 때 super().__init__() 사용하는 이유? + 부모 클래스가 2개 이상인 경우

SKJun 2024. 1. 8. 09:48

super().__init__()를 사용하는 이유는 파이썬 클래스에서 상속을 다룰 때 중요합니다. super() 함수는 자식 클래스에서 부모 클래스의 메서드에 접근할 수 있게 해주며, 이는 특히 초기화 메서드 __init__에 자주 사용됩니다.

 

클래스 만들 때 super().__init__() 사용하는 이유

  1. 코드 재사용: 부모 클래스의 초기화 코드를 재사용하여 중복을 줄일 수 있습니다.
  2. 확장성: 부모 클래스의 초기화 과정이 변경되어도, 자식 클래스 코드를 수정할 필요가 없습니다.
  3. 다중 상속 지원: 여러 부모 클래스들의 __init__ 메서드를 호출할 때 super()를 사용하여 각각의 부모 클래스를 적절하게 초기화할 수 있습니다.

 

예시

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # 부모 클래스의 __init__ 호출
        self.breed = breed

# 사용 예
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name)  # "Buddy" 출력
print(my_dog.breed) # "Golden Retriever" 출력

 

 

이 예시에서 Dog 클래스는 Animal 클래스를 상속받습니다. Dog__init__ 메서드에서 super().__init__(name)을 호출함으로써, Animal 클래스의 초기화 코드를 재사용합니다. 이렇게 하면 Dog 객체가 생성될 때 name 속성이 부모 클래스에 의해 적절히 설정되고, 추가적인 breed 속성은 Dog 클래스에서 설정됩니다.

 


 

super()를 사용해 부모 클래스의 다른 메서드를 호출하는 것도 가능합니다. __init__ 메서드 외에 다른 메서드를 호출하고자 할 때도 super() 함수를 사용하여 부모 클래스의 메서드에 접근하고 이를 실행할 수 있습니다. 이는 클래스의 메서드 재정의(overriding)가 일어날 때 특히 유용합니다.

 

예를 들어, 부모 클래스에 speak 메서드가 있고, 자식 클래스에서 이 메서드를 확장하거나 변경하고 싶을 때, 부모 클래스의 speak 메서드를 super()를 통해 호출할 수 있습니다.

 

예시

class Animal:
    def speak(self):
        print("Animal makes a sound")

class Dog(Animal):
    def speak(self):
        super().speak()  # 부모 클래스의 speak 메서드 호출
        print("Dog barks")

# 사용 예
my_dog = Dog()
my_dog.speak()
# "Animal makes a sound"
# "Dog barks" 출력

 

이 예시에서 Dog 클래스는 Animal 클래스의 speak 메서드를 재정의합니다. 그럼에도 불구하고 Dogspeak 메서드 내에서 super().speak()를 호출함으로써, 먼저 부모 클래스의 speak 메서드를 실행하고 그 다음에 추가적인 동작(여기서는 "Dog barks"를 출력)을 수행합니다. 이렇게 함으로써, 부모 클래스의 기능을 유지하면서 자식 클래스에서 추가적인 기능을 구현할 수 있습니다.

 


 

super()를 한 마디로 요약하자면, 그것은 "부모 클래스의 인스턴스를 참조하는 것"입니다. 이 표현은 super() 함수의 주된 기능을 간결하게 설명하지만, 몇 가지 중요한 세부 사항이 있습니다:

 

  1. 메서드 연결: super()는 부모 클래스의 메서드에 접근하는 것이 주 목적입니다. 이를 통해 부모 클래스의 메서드를 호출하거나, 재정의된 자식 클래스의 메서드에서 부모 클래스의 구현을 활용할 수 있습니다.
  2. 상속 구조 내에서의 상호작용: super()는 상속 체인 내의 다른 클래스들과 상호작용하는 데 사용됩니다. 즉, 단순히 부모 클래스만이 아니라, 복잡한 다중 상속 시나리오에서 적절한 메서드 해석 순서를 따르게 합니다.
  3. 동적 결정: 파이썬의 super()는 컴파일 시간이 아닌 런타임에 동작을 결정합니다. 즉, 프로그램이 실행될 때 해당 상속 구조에 따라 어떤 부모 클래스의 메서드를 호출할지 결정합니다.

 

결론적으로, super()는 부모 클래스의 인스턴스에 접근하는 것이지만, 이것은 주로 메서드 호출과 상속 구조에서의 상호 작용을 위한 것입니다.


부모 클래스가 두개 이상인 경우

파이썬에서 부모 클래스가 두 개 이상인 경우, 즉 다중 상속 상황에서 super()의 사용은 좀 더 복잡해집니다. 다중 상속에서 super()는 파이썬의 메서드 해석 순서(Method Resolution Order, MRO)를 따릅니다. MRO는 클래스가 상속된 순서를 정의하며, 이 순서는 클래스 정의에서 부모 클래스가 나열된 순서에 따라 결정됩니다.

 

다중 상속에서 super()를 사용할 때, 파이썬은 MRO를 사용하여 어떤 부모 클래스의 메서드를 호출할지 결정합니다. 이는 한 클래스가 다른 모든 부모 클래스의 메서드에 접근할 수 있도록 보장합니다.

 

예시

class Base:
    def method(self):
        print("Base method")

class A(Base):
    def method(self):
        print("A method")
        super().method()

class B(Base):
    def method(self):
        print("B method")
        super().method()

class C(A, B):
    def method(self):
        print("C method")
        super().method()

# 사용 예
c_instance = C()
c_instance.method()
C method
A method
B method
Base method

 

이 예시에서 C 클래스는 A와 B 클래스를 상속받습니다. C의 method에서 super().method()를 호출하면, MRO에 따라 먼저 A의 method, 그 다음 B의 method, 마지막으로 Base의 method가 순서대로 호출됩니다.

 

다중 상속의 MRO는 클래스 자체에 __mro__ 속성을 조회함으로써 확인할 수 있습니다. 이 속성은 해당 클래스와 부모 클래스들의 호출 순서를 튜플로 나타냅니다.

 

다중 상속은 복잡한 상속 체인과 예기치 않은 동작을 초래할 수 있으므로, 사용할 때는 주의해야 합니다. MRO와 super()의 정확한 동작을 이해하는 것이 중요합니다.

728x90
반응형