파이토치 learning rate scheduler 소스 코드를 뜯어보다가 베이스 클래스인 _LRScheduler가 object를 상속받는 것을 알 수 있었다. 클래스 __init__과정에서 super().__init__()도 수행하지 않는데, 즉 어떤 속성도 상속받지 않는데 대체 그럼 object를 상속받는 건 무슨 역할을 하는 것일까 하는 궁금증에 찾아본 내용을 정리한다.
old-style class vs. new-style class
class _LRScheduler(object):
def __init__(self, optimizer, last_epoch=-1, verbose=False):
# Attach optimizer
if not isinstance(optimizer, Optimizer):
raise TypeError('{} is not an Optimizer'.format(
type(optimizer).__name__))
self.optimizer = optimizer
# Initialize epoch and base learning rates
if last_epoch == -1:
for group in optimizer.param_groups:
group.setdefault('initial_lr', group['lr'])
else:
for i, group in enumerate(optimizer.param_groups):
if 'initial_lr' not in group:
raise KeyError("param 'initial_lr' is not specified "
"in param_groups[{}] when resuming an optimizer".format(i))
self.base_lrs = [group['initial_lr'] for group in optimizer.param_groups]
self.last_epoch = last_epoch
→ 앞에서 밝힌 바와 같이 object를 상속받았음에도 불구하고 object에 어떠한 의존성도 보이지 않는다.
결론부터 말하자면, object를 상속받는 것은 python3 버전에서는 특별한 기능을 하지 않는다. 그냥 클래스를 선언하는 하나의 방식 중 하나일 뿐이다. 따라서, 생략이 가능하다.
object를 상속받는 것을 specify하는 부분이 생기게 된 유래는, python2 (2.2 이전)에서 python built-in 타입의 상속이 불가능한 문제때문이다. dict나 list와 같은 파이썬 내장 자료구조를 상속 받아서 새로운 클래스를 생성하는 게 불가능했다. (스크래치로 빌트인을 user-defined class로 구현해도 C 코드에서 호환이 되지 않음)
따라서, python 2.2 이상 버전에서는 object 타입을 도입해서 이를 상속받아 기존의 빌트인 타입 상속 문제를 해결하고자 했다. 그러나, 기존 코드를 다 수정해야하는 번거로움을 막기 위해 old-style class와 new-style class로 분리하여 기존의 빌트인 타입 상속이 불가한 클래스와 가능한 클래스를 병존하도록 하였다.
# python 2 (2.2 이상)
## old-style class
class Old:
pass
## new-style class
class New(object):
pass
issubclass(Old, object) # False
issubclass(New, object) # True
그러나, python3에서는 old-style class를 제거하고 new-style class로 통합하였다. new-style class로 통합이 되면서 클래스 선언 시 더 이상 object를 명시적으로 상속받을 필요가 없어졌다.
# Python3
class CustomClass1:
pass
class CustomClass2(object):
pass
class CustomClass3():
pass
issubclass(CustomClass1, object) # True
issubclass(CustomClass2, object) # True
issubclass(CustomClass3, object) # True
위의 3가지 방식 중 어떤 식으로 클래스를 선언하든 모두 object를 상속받는 new-style class로 생성된다.
그럼에도 불구하고, object를 명시해주는 것은 기존 python2 코드와의 호환성을 고려한 것일 가능성이 크다 (아니면 그냥 작성자 마음). 따라서, 저런 코드를 보면 그냥 클래스를 선언했구나~ 하고 넘어가면 되겠다.
References
https://riptutorial.com/python/example/1402/new-style-vs--old-style-classes https://hashcode.co.kr/questions/487/object%EB%8A%94-%EC%99%9C-%EC%83%81%EC%86%8D%EB%B0%9B%EB%8A%94-%EA%B1%B4%EA%B0%80%EC%9A%94
https://jh-bk.tistory.com/24
'프로그래밍 > Python ' 카테고리의 다른 글
[matplotlib] plot 글씨체 변경 및 글씨 선명하게 하기 (0) | 2023.02.21 |
---|---|
[python] install error (disutil 관련) (0) | 2022.03.28 |
[python] Counter (0) | 2021.12.09 |
[Python] for ~ else (0) | 2021.12.09 |
[python] getter, setter, property, decorator 정리 (0) | 2021.08.21 |