🐍Python | Django

[Python] Class와 상속(Inheritance)

이줭 2022. 4. 19. 23:02
728x90

파이썬에서의 상속이란 부모 클래스의 속성과 함수를 그대로 물려 받는 것이다. 자식 클래스에서는 물려받은 부모 클래스의 속성과 함수를 사용할 수 있다.

class Parent:
    def __init__(self, name='짱구', age=5):
        self.name = name
       	self.age = age
        
    def introduce(self):
    	print(f'내 이름은 {self.name}이고, 나이는 {self.age}살이야.')
        
class Child:
    def __init__(self):
    	super().__init__()
        
child = Child()
child.introduce() # 내 이름은 짱구이고, 나이는 5살이야.

일반적인 메서드 오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 재정의 하는 것이고, 재정의 후 호출하면 부모 클래스의 메서드는 무시되고 자식 클래스의 메서드가 호출된다.

 

부모클래스의 메서드를 자식 클래스에서 이용하면서, 필요한 부분만 재정의하여 사용하는 경우 super()를 통해 재정의 할 수 있다.

class Parent:
    def __init__(self, name='짱구', age=5):
        self.name = name
       	self.age = age
        
    def introduce(self):
    	print(f'내 이름은 {self.name}이고, 나이는 {self.age}살이야.')
        
class Child:
    def __init__(self):
    	super().__init__()
        
    def introduce(self):
    	super().introduce()
        print(f'내 이름은 {self.name}이고, 나이는 비밀이야.')
        
child = Child()
child.introduce() 

# 내 이름은 짱구이고, 나이는 5살이야.
# 내 이름은 짱구이고, 나이는 비밀이야.

MRO(Method Resolution Order)는 상속과 관련있는 개념이다. 파이썬에서는 다중 상속이 가능하며, 상속 개수의 제한이 없다. 만약 상속받는 부모 클래스들이 동일한 메서드명을 사용하고 있다면, 어떤 메서드를 호출해야하는지 모르는 문제가 발생한다. 하나의 구문이 두 가지 이상의 의미로 해석될 수 있고, 이를 MRO를 통해 해결한다.

 

MRO는 자식과 부모 클래스들을 전부 포함하여 메서드의 실행 순서를 지정하는 것이다.

MRO는 __mro__라는 속성(튜플)을 통해 확인할 수 있다.

print(Child.__mro__)

(<class '__main__.Child'>, <class '__main__.Parent>, <class 'object'>)

위와 같이 확인할 수 있고, 다음의 순서를 따른다.

자식클래스 → 부모클래스(먼저 상속받은 순서대로) 부모클래스의 부모클래스 최상위 object

 

 

만약 다음과 같은 상황이라면 어떤 결과를 출력하게 될까?

class Human:
    def say(self):
    	print('안녕')
        
class Mother:
    def say(self):
        super().say()
        
class Father:
    def say(self):
        print('아빠')
        
class Son(Mother, Father):
    pass
    
son = Son()
son.say()

# 출력 값은?????
# 아빠

Mother의 클래스의 메서드가 super 클래스의 say 메서드를 호출하므로 '안녕'을 출력할거라 생각할수도 있지만, Son 클래스의 MRO를 살펴보면

print(Son.__mro__)

(<class '__main__.Son'>, <class '__main__.Mother'>, <class '__main__.Father'>, 
    <class '__main__.Human'>, <class 'object'>)

위와 같이 MRO에 의해 Mother 클래스의 super 클래스가 다음 우선순위를 가지는 Father 클래스를 가리키게 된 것이다.

 

만약 MRO를 정상적으로 생성할 수 없을 경우 에러가 발생한다. 예를 들어

class A:
    pass
    
class B(A):
    pass
    
class C(A):
    pass
    
class D(A, B, C): # Error 발생
    pass

위와 같은 경우, D 클래스에서 A 클래스를 먼저 상속 받았으니 우선 순위를 가지게 되는데 B, C가 A를 상속 받고 있으니 호출순서가 모순적인 상황이 되고, 따라서 에러가 발생한다.

 

다른 예를 들어보면

class A:
    pass
    
class B:
    pass
    
class C(A, B):
    pass
    
class D(B, A):
    pass
    
class E(C, D): # Error 발생
    pass

위의 경우도 C, D 클래스가 각각 교차된 순서로 부모의 상속을 받기 때문에 E 클래스에서 호출순서를 정할 수 없는 모순적인 상황에 놓이기에 에러가 발생한다.

 

이렇게 상속과 MRO에 대해 간단히 알아보았다. 끝~!

 

참고 : https://tibetsandfox.tistory.com/26

728x90

'🐍Python | Django' 카테고리의 다른 글

[Python] 메타클래스(MetaClass)  (0) 2022.04.27
[Python] main 함수  (0) 2022.04.26
[Python] Decorator  (0) 2022.04.18
[Python] Under Score(_)?  (0) 2022.04.14
[Python] String join()/split()  (0) 2022.02.07