36.3 기반 클래스의 속성 사용하기

이번에는 기반 클래스에 들어있는 인스턴스 속성을 사용해보겠습니다. 다음과 같이 Person 클래스에 hello 속성이 있고, Person 클래스를 상속받아 Student 클래스를 만듭니다. 그다음에 Student로 인스턴스를 만들고 hello 속성에 접근해봅니다.

class_inheritance_attribute_error.py

class Person:
    def __init__(self):
        print('Person __init__')
        self.hello = '안녕하세요.'
 
class Student(Person):
    def __init__(self):
        print('Student __init__')
        self.school = '파이썬 코딩 도장'
 
james = Student()
print(james.school)
print(james.hello)    # 기반 클래스의 속성을 출력하려고 하면 에러가 발생함


실행 결과

Student __init__
파이썬 코딩 도장
Traceback (most recent call last):
  File "C:\project\class_inheritance_attribute_error.py", line 14, in <module>
    print(james.hello)
AttributeError: 'Student' object has no attribute 'hello' 

실행을 해보면 에러가 발생합니다. 왜냐하면 기반 클래스 Person__init__ 메서드가 호출되지 않았기 때문입니다. 실행 결과를 잘 보면 'Student __init__'만 출력되었습니다.

즉, Person__init__ 메서드가 호출되지 않으면 self.hello = '안녕하세요.'도 실행되지 않아서 속성이 만들어지지 않습니다.

36.3.1  super()로 기반 클래스 초기화하기

이때는 super()를 사용해서 기반 클래스의 __init__ 메서드를 호출해줍니다. 다음과 같이 super() 뒤에 .(점)을 붙여서 메서드를 호출하는 방식입니다.

  • super().메서드()

class_inheritance_attribute.py

class Person:
    def __init__(self):
        print('Person __init__')
        self.hello = '안녕하세요.'
 
class Student(Person):
    def __init__(self):
        print('Student __init__')
        super().__init__()                # super()로 기반 클래스의 __init__ 메서드 호출
        self.school = '파이썬 코딩 도장'
 
james = Student()
print(james.school)
print(james.hello)

실행 결과

Student __init__
Person __init__
파이썬 코딩 도장
안녕하세요.

실행을 해보면 기반 클래스 Person의 속성인 hello가 잘 출력됩니다. super().__init__()와 같이 기반 클래스 Person__init__ 메서드를 호출해주면 기반 클래스가 초기화되어서 속성이 만들어집니다. 실행 결과를 보면 'Student __init__''Person __init__'이 모두 출력되었습니다.

기반 클래스 Person의 속성 hello를 찾는 과정을 그림으로 나타내면 다음과 같은 모양이 됩니다.

그림 36-4 기반 클래스의 속성을 찾는 과정

36.3.2  기반 클래스를 초기화하지 않아도 되는 경우

만약 파생 클래스에서 __init__ 메서드를 생략한다면 기반 클래스의 __init__이 자동으로 호출되므로 super()는 사용하지 않아도 됩니다.

class_inheritance_no_init.py

class Person:
    def __init__(self):
        print('Person __init__')
        self.hello = '안녕하세요.'
 
class Student(Person):
    pass
 
james = Student()
print(james.hello)

실행 결과

Person __init__
안녕하세요.

이처럼 파생 클래스에 __init__ 메서드가 없다면 기반 클래스의 __init__이 자동으로 호출되므로 기반 클래스의 속성을 사용할 수 있습니다.

참고 | 좀 더 명확하게 super 사용하기

super는 다음과 같이 파생 클래스와 self를 넣어서 현재 클래스가 어떤 클래스인지 명확하게 표시하는 방법도 있습니다. 물론 super()와 기능은 같습니다.

super(파생클래스, self).메서드

class Student(Person):
    def __init__(self):
        print('Student __init__')
        super(Student, self).__init__()     # super(파생클래스, self)로 기반 클래스의 메서드 호출
        self.school = '파이썬 코딩 도장'