백준 같은 온라인 저지 사이트를 이용하다 보면 가끔 이런 코드를 볼 수 있습니다(저도 자주 사용하고요).
input = sys.stdin.readline
백준에서 python을 이용해서 문제를 풀다 보면 어느 순간(특히 반복해서 입력을 받는 문제를 풀 때) sys.stdin.readline() 메서드를 사용해본 분들이 많으실 겁니다. 실제로 python을 이용한 반복문 문제 중에 위 메서드를 써야만 하도록 구성된 문제가 있기도 하고요. 자세히는 잘 모르겠지만 input()보다 sys.stdin.readline()이 더 빠르다는 얘기가 있으니까 이걸 써서 문제를 해결하신 분들도 많을 겁니다(왜 더 빠른지에 대한 글을 작성 중입니다. 조만간 게시할 수 있도록 노력해보겠습니다). 근데 input에 비하면 너무 길고 여러 번 저걸 직접 작성하다 보면 오타가 날 가능성도 높겠죠. 복사하려고 왔다 갔다 하는 것도 귀찮고요.
그래서 저런 식으로 변수에다가 함수를 담아서 사용을 하곤 합니다. 그러면 sys.stdin.readline() 메서드를 input()이라고 써도 호출할 수 있기 때문이죠(물론 이미 input()이라는 빌트인 함수가 존재하기 때문에 저는 보통 앞글자를 따서 ssr이라고 변수 선언을 하는 편입니다). 이제까지는 별생각 없이 해당 기능을 잘 사용해왔는데 문득 해당 기능의 이름이 무엇인지 궁금해져서 찾아보기 시작했습니다.
사실 이 기능의 이름이 궁금해진 건 다른 이유였는데요. 최근에 오버라이딩에 대해 공부를 하다가 제가 해봤던 방법 중에 오버라이딩이 있었나? 하고 기억을 더듬던 와중에 위 기능이 생각났습니다. 그래서 아~ 이게 오버라이딩이었구나 하고 넘어가려던 찰나, 오버라이딩은 메서드 이름을 변경하는게 아니라 같은 이름의 다른 기능으로 만드는 거 아니었나? 하고 브레이크가 걸렸습니다. 그래서 가만히 생각을 해보니 이게 오버라이딩이 아니겠구나 싶었어요. 그러면 도대체 이건 뭐지? 하고 검색을 하기 시작했습니다.
함수 이름 재정의, 함수 이름 변경 등등의 검색어들로 검색을 해봤었지만 그다지 만족스러운 글은 찾을 수 없었습니다. 그러다 문득 이게 함수 자체를 바꿔버리는 것은 아닐 거고, 원래 있던 메서드를 해당 이름으로 호출할 수 있는 기능 아니던가? ▶ 그럼 이건 함수의 주소를 가리키는 포인터인가? ▶ 애초에 파이썬은 변수 할당할 때 주소 참조로 할당하는 거 아니던가? ▶아 이게 변수 이름이구나? 하고 생각이 발전해서 함수를 변수로 라고 검색을 했더니 얼추 제가 알고 싶었던 내용에 근접한 글들을 조금 찾을 수 있었습니다.
결론부터 말하자면 '파이썬의 함수는 일급 객체(Fiirst Class Object)로서 다른 객체들에 일반적으로 적용할 수 있는 모든 연산을 지원한다'라고 합니다. 일단 일급 객체라는 말은 무시하고 파이썬의 함수는 파이썬에서 제공하는 어지간한 연산들을 다 적용가능하다는 얘기죠. 아하~ 그래서 저렇게 변수로 함수를 할당하더라도 아무 문제없이 사용가능하구나~ 근데 일급객체는 뭐지? 이젠 또 일급객체를 찾아보기 시작했습니다.
일급객체라는 말은 단순히 파이썬에서만 쓰는 말이 아니라 컴퓨터 프로그래밍 분야 전반에서 사용하는 명칭이더라고요. 위에서 적었던 말과 동일한데 요는, 프로그래밍 언어에서 지원하는 거의 모든 연산이 적용 가능한 객체를 의미합니다. 예를 들면 숫자나 문자가 있을 수 있겠죠. 어떤 함수에 파라미터로서 넘겨줄 수도 있고, 수정도 가능하고, 대입도 가능하고 등등(사실 본질적으로 보면 결국 파라미터로서 사용한다는 같은 말이긴 합니다). 파이썬 같은 경우 그런 일급 객체에 함수가 포함이 된다는 얘기죠. 일급객체에 대해서 좀 더 궁금하신 분은 위키를 참조하시길 바랍니다. https://ko.wikipedia.org/wiki/%EC%9D%BC%EA%B8%89_%EA%B0%9D%EC%B2%B4
이번 포스팅에서는 파이썬에서 함수나 메서드를 변수로 할당할 수 있는(이름을 바꿀 수 있는) 이유에 대해서 알아봤습니다. 별로 중요하지 않아 보일 순 있지만 은근히 이렇게 이유를 알고 나면 다른 걸 배울 때 배경지식으로서 작용하는 경우가 제법 있습니다(검색하다 보니 이렇게 메서드를 지역변수로 할당해놓으면 선언 없이 사용할 때에 비해서 조금 빨라진다고 하네요. 아마 로컬 네임스페이스에서 바로 접근을 하기 때문인 것으로 보이는데 해당 내용도 한 번 정리를 해보겠습니다). 이 글을 쓰면서도 찾다 보니 관련된 정보가 막 쏟아져 나오네요. 심지어 이게 함수의 주소를 가리키는 포인터인가? 하고 생각만 했던 것도 진짜로 함수 포인터라는 내용이 있었습니다. 정말 공부에는 끝이 없군요.
'Uncategorized' 카테고리의 다른 글
[Javascript]var, let 그리고 hoisting에 대해 알아보자 (0) | 2023.11.08 |
---|---|
ChatGPT란 (0) | 2023.02.11 |
[Python]파이썬 코드는 어떻게 작성해야할까? - PEP 8 (0) | 2022.11.22 |
사이트 페이지 로딩 시간 측정하기 (0) | 2022.11.14 |