python 으로 코드를 짜다보면 자주 맞이하게되는
self
몇 개월 짜봤다하면 , 다른 언어에서의this
와 비슷한 놈임을 직감적으로 알 수 있다. 근데 python에는 조금 더 신기한 부분들이 있다.
python은 굉장히 객체지향적인 언어이다. Primitive타입이 존재하지 않으며 , 모든 것은 객체로 다뤄지기 때문이다.
예를들어 , 생각없이 사용하고 있는 True
와 False
를 vscode
와 같은 ide에서 python 플러그인을 설치하고 코딩하다보면 위의 두 자료형은 사실 bool
클래스의 singleton instance인 것을 알 수 있다.
str
, int
, bool
등은 전부 class
이다. 근데, 전부 lower case start인게 너무 마음에 걸린다. type hint
를 때려박아도 복잡도가 높아질수록 골머리가 아파온다. Go
를 배우도록하자) 사족이 조금 길어졌지만 , 우리는 python에서 다음과 같이 class를 설계한다.
class TestClass:
def __init__(self):
# some thing init instace
def foo(self,test_string : str) -> None:
print(self.name)
print(test_string)
왜 class의 method의 첫 번째 인자로 항상 instacne
자기 자신을 가르키는 self
가 와야할까?
지금 위의 제목을 읽고 분명
ㅋㅋ 컴알못이네 당연히 class는 메모리에 존재하는 값이겠지
생각하고 있을 거 뻔히 안다. 맞다 , 맞는 말이다.
class가 값이라는 말은 class는 메모리에 존재하는 데이터의 덩어리일 뿐이고
그 안의 모든 메소드들은 class라는 덩어리에 얽힌 또 하나의 덩어리이다.
"윙? 무슨 말이야?" 라고 생각이 들 것 같다.
class TestClass2:
def foo()->None:
print("hello!")
def foo2(self)->None:
print(self.name)
def main():
TestClass2.foo() # hello!
위와 같이 , method에 self라는 인스턴스를 넘기지 않아도 class는 namespace의 역활만 할 뿐 method를 class를 통해서 호출이 가능하다.
우리가 습관처럼 self
라는 인자를 method
맨 처음에 넣어주는 이유는 해당 인스턴스의 attribute
에 접근하기 위해서 인자를 넣어주는 것이다.
def main()
test_instance = Test()
test_instace.foo2() # david
위와 같이 , 인스턴스를 통해서 foo2를 호출하게된다면 해당 인스턴스가 self
라는 인자로 method에 넘겨지게 되며 위의 예시는 사실
def main()
test_instance = Test()
Test.foo2(test_instacne)
다음과 완벽하게 동치이다. 즉 , python
인터프리터는 class의 namespace함수로서 메소드를 다루며. 만일 메소드가 특정 인스턴스를 통해서 callee
가 되었을경우 위와 같이 해석하여 첫 번째 인자로 해당 caller
인스턴스를 첫 번째 인자로 넣어준다.
그렇기때문에 우리는 항상 첫 번째 인자로 self
를 무의식적으로 넣어줬던 것이다.
pythonic한 코드를 짤 수 있도록 매일 노력하자!
데코레이터 , class 등은 높은 수준의 추상화를 제공하지만 이에 전적으로 의지하지말자
한번 더 왜 그럴까?
를 고민해보는 개발자가 되자.