본문 바로가기
Python

super()

by yororing 2024. 7. 25.

00 개요

  • 회사에서 코드분석 중 super().~라는 함수가 나오길래 이에 대해 정리하고자 함

 

01 super() 

1. 정의 및 개념

  • super()라는 함수는 super class 즉, 부모/자매 클래스의 임시적인 객체 (proxy object)를 반환하여 부모/자매 클래스의 메소드에 접근 가능하게끔 함
  • 메소드를 불러와 사용하는 것이지, 부모 클래스의 인스턴스 속성 자체를 변화시키는 것은 아님!

2. 빠른 예시

class Parent:
    def __init__(self, txt):
        self.message = txt
    def printmessage(self):
        print(self.message)

class Child(Parent):
    def __init__(self, txt):
        super().__init__(txt)

>>> x = Child("Hello, and welcome!")
>>> x.printmessage()
Hello, and welcome!

 

3. 자세한 예시

  • 아래의 예시를 통해 부모 클래스의 인스턴스 속성은 자식 클래스에 상속되지 않음을 확인
class Human:
    '''Super Class'''
    def __init__(self):
        # instance 속성
        self.name = '사람이름'
        self.age = '나이'
        self.city = '도시'
    def show(self):
        print('사람 클래스의 메소드입니다.')

class Student(Human):
    '''Child Class'''
    def __init__(self, name):
        self.name = name
    
    def show_name(self):
        print('이름은', self.name)
        
    def show_age(self):
        print('나이는: ', self.age)

>>> a = Student('Pearl')
>>> a.show()			# 메소드 상속
사람 클래스의 메소드입니다.
>>> a.show_name()		# 자식노드에서 재정의된 속성
이름은 Pearl
>>> a.show_age()		# 부모 클래스의 속성을 상속 시도
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in show_age
AttributeError: 'Student' object has no attribute 'age'

 

  • 상속되지 않는 이유:
    • 인스턴스 속성이 생기는 시기: 부모 클래스의 인스턴스 속성은 부모 클래스 객체가 형성될때 __init__ 매직 메소드가 실행되면서 생성됨
    • 그러나 자식 클래스 어디에도 부모 클래스의 객체가 형성된 적이 없음
    • 그래서 super() 함수를 이용하여 부모 클래스의 __init__() 매직 메소드를 자식 클래스에 실행시키면 부모 클래스의 속성 상속 가능
    • super().__init__() 
  • super().__init__()의 역할:
    • 부모 클래스의 __init__() 매직 메소드를 자식 클래스의 __init__() 매직 메소드에서 실행 하려면, 즉 자식 클래스에도 부모 클래스의 인스턴스 속성과 동일한 속성이 생성되게 하려면 자식 클래스의 def __init__(): 메소드에서 super().__init__()을 선언해주면 됨
class Human:
    '''Super Class'''
    def __init__(self):
        # instance 속성
        self.name = '사람이름'
        self.age = '나이'
        self.city = '도시'
    def show(self):
        print('사람 클래스의 메소드입니다.')

class Student(Human):
    '''Child Class'''
    def __init__(self, name):
        super().__init__()
        self.name = name
    
    def show_name(self):
        print('이름은', self.name)

    def show_age(self):
        print('나이는', self.age)

>>> a = Student('Yoon')
>>> a.show()			# 메소드 상속
사람 클래스의 메소드입니다.
>>> a.show_name()		# 자식노드에서 재정의된 속성
이름은 Yoon
>>> a.show_age()		# 부모 클래스의 속성을 상속 성공
나이는 나이
  • super().부모클래스_메소드()의 역할:
    • 부모 클래스의 메소드를 자식 클래스에서 직접 사용할 수 있음
class Human:
    '''Super Class'''
    def __init__(self):
        # instance 속성
        self.name = '사람이름'
        self.age = '나이'
        self.city = '도시'
    def show_everything(self):					# show_everything()로 변경
        print('사람 클래스의 메소드입니다.')
        print(f'이름: %s, 나이: %s, 도시: %s' % (self.name, self.age, self.city))

class Student(Human):
    '''Child Class'''
    def __init__(self, name):
        super().__init__()
        self.name = name
    
    def show_name(self):
        super().show_everything()
        print('입력받은 이름:', self.name)

    def show_age(self):
        print('나이:', self.age)

>>> a = Student('Parmiss')
>>> a.show_name()
사람 클래스의 메소드입니다.
이름: Parmiss, 나이: 나이, 도시: 도시
입력받은 이름: Parmiss
  • 여기서 주의할 점은, 메소드를 불러와 사용하는 것이지, 부모 클래스의 인스턴스 속성 자체를 변화시키는 것은 아님!
  • 다음과 같이 super().__init__()을 선언하는 순서를 바꾸면 부모클래스의 속성으로 재정의 되는 것을 확인 가능
class Human:
    '''Super Class'''
    def __init__(self):
        # instance 속성
        self.name = '사람이름'
        self.age = '나이'
        self.city = '도시'
    def show_everything(self):
        print('사람 클래스의 메소드입니다.')
        print(f'이름: %s, 나이: %s, 도시: %s' % (self.name, self.age, self.city))

class Student(Human):
    '''Child Class'''
    def __init__(self, name):
        self.name = name		# 순서 변경
        super().__init__()		# 순서 변경
    
    def show_name(self):
        super().show_everything()
        print('입력받은 이름:', self.name)

    def show_age(self):
        print('나이:', self.age)

>>> a = Student('Rose')    
>>> a.show_name()
사람 클래스의 메소드입니다.
이름: 사람이름, 나이: 나이, 도시: 도시
재정의 후 Human클래스의 이름: 사람이름
  • 위의 예시 및 결과값을 보면 super().__init__() 의 순서에 따라 초기화 내용이 달라지는 것을 확인
  • 설명:
    • class Student(Human)의 def __init__(self, name): 에서
    • self.name = name 이 먼저 업데이트 됨
    • 후에 super().__init__() 에 의해 임시적인 부모 클래스의 self.name = '사람이름' 으로 다시 바뀌게 됨
    • 최종적으로는 class Human()의 self.name = '사람이름' 속성으로 정의되어서 name = '사람이름' 으로 할당되어 출력됨

참조

  1. https://docs.python.org/3/library/functions.html#super
  2. https://supermemi.tistory.com/entry/Python-3-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%98-super-%EC%97%90-%EB%8C%80%ED%95%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90-superinit-super%EC%9D%98-%EC%9C%84%EC%B9%98 
  3.  
  4.  
  5.