Introduction
남의 파이썬 코드를 보다 보면, 종종 다음과 같은 형태의 클래스 선언과 마주하게 된다.
class MyClass(object):
# blah blah...
일단은 해당 라인만 보면 내가 선언한 클래스가 object 클래스를 상속 받아서 뭔가를 하고 있는 것처럼 보인다. 하지만 스크롤을 더 내려 봐도 상속을 받아서 따로 하는 것도 없어 보이고, 심지어는 object 상속을 제거해도 코드는 아무런 에러 없이 멀쩡히 돌아간다!
대체 이건 용도가 무엇이며 왜 굳이 넣는 걸까?
결론부터 말하자면,
- 파이썬 3에서의 object 상속은 표기상의 차이 이외에 상속 관계가 없는 클래스 선언과 아무런 차이점이 없다.
- 파이썬 2 (정확히는 2.2 이상) 에서는 클래스에 object를 명시적으로 상속시켜 줘야 비로소 우리가 파이썬 3에서 흔히 쓰는 클래스가 된다.
- 파이썬 3 코드에서 굳이 object를 상속시켜 주는 이유는 대개 파이썬 2와의 호환성 혹은 작성 취향 때문이다.
자세한 설명에 대해선, 아래에서 간단히 알아보자.
먼저 이런 요상한 라인이 만들어지게 된 배경부터 보자.
Critical flaw in eariler Python design
2.2 이전의 초기 파이썬 설계에는 클래스의 상속에 관련해서 한 가지 치명적인 결함이 있었는데, 바로 C로 구현된 파이썬 클래스의 subclass를 만들 수 없다는 것이었다. 이로 인해 종류에 상관 없이 파이썬 내장 (built-in) 타입을 상속받는 user-defined subclass를 생성하는 것 또한 막혀 있었다.
하나의 예시를 들자면, 기존에 사용하고 있던 list 타입의 subclass를 만들고 간단한 메서드 하나를 추가하는 작업도 근본적으로는 불가능한 일이었다. 어찌저찌 list의 모든 메서드를 그대로 구현해 새로운 클래스를 만들어 내도, 일반적인 list 클래스가 아니라는 이유로 많은 C 코드에서 호환이 되지 않는 문제가 있었다.
Old-style class와 New-style class
위 문제는 꽤 심각했기 때문에, 파이썬 2.2 업데이트에서 해당 문제와 관련한 큰 업데이트가 있었다. 클래스가 파이썬 빌트인 타입을 상속받지 못 하는 문제를 해결함과 동시에 이것저것 클래스에 관련된 기능들이 추가 될 예정이었는데....
기존의 간단한 기능만을 가지는 클래스 형태를 선호하는 유저들이 꽤 있었던 데다, 이미 작성되어 있는 코드들은 업데이트에 영향을 받지 않고 그대로 사용할 수 있도록 만들어야 했기 때문에, 이런 새로운 형태의 클래스를 선언하기 위해서는 다음과 같이 object 를 상속시키도록 만들었다.
# Python 2.2 ~ 2.7
class MyNewClass(object):
# New-style class
...
class MyOldClass():
# Old-style class
기존처럼 딱히 상속을 받지 않아 괄호를 비워둔 클래스 선언은 그대로 이전 버전의 클래스(old-style class) 가 만들어지도록 하고, object를 상속받는 클래스는 새로운 버전의 클래스(new-style class) 가 만들어지도록 한 것이다.
그리고 이전의 int, list, dict 등등과 같은 빌트인 타입들은 전부 object의 subclass로 변경시켜 new-style 클래스로 취급되도록 하고, 이들을 상속받는 (이제는 상속이 가능해졌다!) user-defined 클래스 또한 new-style 클래스로 만들어지도록 설계했다.
New-style 클래스로 오면서 추가된 다른 주요한 기능으로는 static method와 class method, 그리고 property 기능이 있으며, 이렇게 기능이 개선된 new-style 클래스 형태가 지금 우리가 파이썬 3에서 사용하고 있는 기본 클래스가 된다.
Class in Python 3
그러면 파이썬 3.0으로 넘어오면서 old-style class는 어떻게 되었을까? 아쉽게도 new-style 클래스가 디폴트가 되면서 사라졌다. 파이썬 3에선 old-style class를 만들 수 있는 방법은 공식적으론 없으며, 모든 클래스는 object를 상속받는 new-style class라고 보면 된다.
이에 따라 상속 없이 디폴트로 클래스를 생성하는 방식에도 변화가 생겼다.
# Python 3
class MyClass():
# New-style class
class MyClass(object):
# New-style class
class MyClass:
# New-style class
괄호를 비워 놓아도, object를 상속 시켜도, 괄호를 적지 않아도 모두 object를 상속받는 new-style class가 생성된다! 거의 클래스 선언 계의 답정너라고 볼 수 있다.
따라서 지금은 이렇게 파이썬 3부터 new-style class가 표준이 되면서 object를 굳이 상속 란에 넣어주는 것이 의미가 없는 행동이 되었지만, 파이썬 2와의 호환성을 위해 남겨두는 경우도 있으며, 기능적인 의미는 없지만 단지 명확성을 위해 적어두는 경우도 종종 있는 것 같다.
이번에 소개할 내용은 여기까지다.
비슷한 궁금증을 가지고 있던 사람들에게 도움이 되었으면 좋겠다.
아래는 참고할 만한 사이트이다.
References
2 PEPs 252 and 253: Type and Class Changes
https://docs.python.org/release/2.2.3/whatsnew/sect-rellinks.html
Why do Python classes inherit object?
https://stackoverflow.com/questions/4015417/why-do-python-classes-inherit-object
New-style Classes
https://www.python.org/doc/newstyle/
What is the difference between old style and new style classes in Python?