Python Super#
super()는 상속 관계에서 부모 클래스의 메서드를 호출하는 데 사용되는 중요한 도구.
부모 클래스(슈퍼클래스)의 메서드를 호출할 때 사용된다. 주로 자식 클래스에서 부모 클래스의 메서드를 확장하거나 재정의할 때 활용된다.
사용 예제:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound"
class Dog(Animal):
def __init__(self, name, breed):
# 부모 클래스의 __init__ 메서드 호출
super().__init__(name)
self.breed = breed
def speak(self):
# 부모 클래스의 speak 메서드를 확장
base_sound = super().speak()
return f"{base_sound} - specifically, a woof!"
# 사용 예시
my_dog = Dog("Rex", "Golden Retriever")
print(my_dog.speak())
# 출력: "Rex makes a sound - specifically, a woof!"
|
- 부모 클래스 참조: super()는 현재 클래스의 부모 클래스를 참조한다.
- 메서드 연결: 부모 클래스의 메서드에 접근하여 호출할 수 있게 한다.
- 동적 결정: 런타임에 메서드 호출을 결정한다.
- MRO(Method Resolution Order) 활용: 다중 상속 시 메서드 해석 순서를 따른다.
- 코드 재사용: 부모 클래스의 코드를 재사용하여 중복을 줄인다.
- 유연성: 부모 클래스의 구현을 변경해도 자식 클래스에서 수정할 필요가 없다.
- 다중 상속 지원: 복잡한 상속 구조에서도 적절한 부모 메서드를 호출할 수 있다.
- 복잡성: 다중 상속 시 상속 구조가 복잡해질 수 있다.
- 예상치 못한 동작: 상속 계층에 따라 의도하지 않은 메서드가 호출될 수 있다.
주요 사용 방법#
- super().init(): 부모 클래스의 생성자를 호출한다.
- super().method_name(): 부모 클래스의 특정 메서드를 호출한다.
super()의 고급 기능과 특징#
다중 상속에서의 활용#
super()는 다중 상속 상황에서 메서드 해결 순서(MRO)를 따라 적절한 메서드를 찾아준다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| class Flying:
def move(self):
return "Flying in the air"
class Swimming:
def move(self):
return "Swimming in the water"
class Duck(Flying, Swimming):
def move(self):
# Flying의 move 메서드 호출
flying_movement = super().move()
return f"{flying_movement} and sometimes swimming too"
class DivingDuck(Swimming, Flying):
def move(self):
# Swimming의 move 메서드 호출
swimming_movement = super().move()
return f"{swimming_movement} and sometimes flying too"
# MRO 확인
print(Duck.mro())
print(DivingDuck.mro())
|
믹스인 패턴에서의 활용#
super()는 믹스인 패턴을 구현할 때 매우 유용하다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| class LoggerMixin:
def log(self, message):
print(f"[LOG] {message}")
def execute_action(self):
self.log("Action started")
result = super().execute_action()
self.log("Action completed")
return result
class Service:
def execute_action(self):
return "Performing action"
class LoggedService(LoggerMixin, Service):
pass
# 사용 예시
service = LoggedService()
service.execute_action()
|
초기화 체인#
super()는 복잡한 클래스 계층에서 초기화를 체인처럼 연결할 수 있다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| class Database:
def __init__(self, db_name):
print(f"Initializing database: {db_name}")
self.db_name = db_name
class Cache:
def __init__(self, cache_size):
print(f"Initializing cache: {cache_size}")
self.cache_size = cache_size
class Application(Database, Cache):
def __init__(self, db_name, cache_size, app_name):
print(f"Initializing application: {app_name}")
super().__init__(db_name)
Cache.__init__(self, cache_size)
self.app_name = app_name
# 사용 예시
app = Application("mydb", 1000, "MyApp")
|
super()의 주의사항과 제약#
초기화 순서 주의
1
2
3
4
5
6
7
8
9
| class Wrong(Base):
def __init__(self):
self.value = 10 # 잘못된 순서
super().__init__()
class Right(Base):
def __init__(self):
super().__init__() # 올바른 순서
self.value = 10
|
다중 상속에서의 복잡성
1
2
| # 복잡한 다중 상속에서는 MRO를 잘 이해해야 함
print(ComplexClass.mro()) # MRO 확인이 중요
|
메서드 시그니처 일관성
1
2
3
4
5
6
7
| class Parent:
def method(self, x, y):
pass
class Child(Parent):
def method(self, x, y): # 동일한 파라미터 유지
super().method(x, y)
|
실제 사용 예시와 모범 사례#
메서드 확장하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| class BaseValidator:
def validate(self, data):
if not data:
raise ValueError("Data cannot be empty")
return True
class NumberValidator(BaseValidator):
def validate(self, data):
# 기본 검증 수행
super().validate(data)
# 추가 검증
if not isinstance(data, (int, float)):
raise ValueError("Data must be a number")
return True
|
초기화 체인 구성하기
1
2
3
4
5
6
7
8
9
10
11
12
13
| class ConfigMixin:
def __init__(self, config):
super().__init__()
self.config = config
class LoggerMixin:
def __init__(self):
super().__init__()
self.logger = self.setup_logger()
class Application(ConfigMixin, LoggerMixin):
def __init__(self, config):
super().__init__(config) # 모든 부모 클래스 초기화
|
참고 및 출처#