오늘도 힙스터 python의 신기한 점을 알아가보자
대부분의 프로그래밍 언어는 함수를 작성할 수 있고 , 함수의 인자를 지정할 수 있으며 , 함수의 인자가 대입되지 않아도 기본으로 값을 지정할 수 있다.
void foo(int test_arg = 3) {
std::cout<<test_arg<<std::endl;
}
int main(int argc,char **argv) {
foo(); // 3
}
물론 우리 python
도 당연히 default argument
를 지원한다.
def foo(test_arg = []):
print(test_arg)
foo() # []
우선 C++
기준으로 PC가 thread를 실행 중 함수의 실행라인에 도달하게 된다면 , 함수의 주소로 jump하게 되고 컴파일러는 해당하는 함수의 stack frame
에 프롤로그
이후 ( 프롤로그는 함수가 끝나고 되돌아갈 ret
와 같은 기본적인 값들을 초기화 하는 과정이다 ) 대입될 인자가 존재하지 않는다면 자동으로 기본 값을 인자에 대입해준다.
즉 , 매번 함수가 호출될때마다 기본값을 호출해준다는 뜻이다.
하지만 , 우리 힙스터 python
은 조금 다르다.
def foo(test_arg = []):
test_arg.append("test",end=' ')
print(test_arg)
foo() # test
foo() # test test
foo() # test test test
...
힙스터 python
은 진짜 모든것이 객체이다. foo라는 함수조차 사실은 class이기 때문에 이런 현상이 벌어지는 것...
foo라는 함수의 기본인자는 class attribute
로서 저장된다. 즉 , 인터프리터가 import 타임에 test_arg
라는 class attributer
를 레퍼런스하게된다.
매 함수의 call마다 mutable
한 인스턴스를 기본인자로 두고 변경할경우 디버깅에 에로사항이 꽃 피는 경험을 할 수 있다.
요즘 fluent python과 python 클린 코딩을 읽고 있는데 생각지도 못한 부분들이 많이
존재하는 것 같다.
열심히 공부하자...!