Python 20

Python Reflection 맛보기

Introspection vs Reflection Python이 가지는 매력 중의 하나는 언어의 많은 부분이 동적이라는 점입니다. Instrospec과 Reflection이 그런 기능 중 일부인데요. Introspection은 실행 시에 object에 대한 정보를 알아내는 것, Reflection은 여기에서 그치지 않고 object에 대한 정보를 수정하는 것을 의미합니다. 엄밀히 두가지의 의미가 다르지만 Reflection으로 합쳐서 부르는 경우가 많습니다. Reflection 기능은 자주 쓰이지는 않지만 알아두면 유용할 때가 있습니다. 예를 들어, 코드 작성 시에는 함수 이름을 모르지만 실행 중에 함수 이름을 알아내서 실행시킨다거나, Python의 Duck typing을 통과하기 위해서 attribut..

Python 2020.06.09

pyc 파일에 대해서

1. *.pyc 파일 Python으로 코딩을 하다 보면 내가 만들지 않은 *.pyc 파일들이 만들어져 있는 것을 볼 수 있습니다. 가끔은 *.pyc가 문제를 일으키기도 하고요 (bad magic number in 'application': b'\x03\xf3\r\n': ImportError) *.pyc는 Python이 *.py를 읽어서 실행시킬 때 자동 생성되는 파일인데, 이는 Python 프로그램이 어떻게 구동되는지와 관련이 있습니다. (이야기를 진행하기에 앞서 한가지 명확히 해야 할 것이 있습니다. 우리가 보통 Python이라고 이야기하지만, Python이라는 것은 프로그래밍 언어이기 때문에 앞으로 이야기할 내용은 엄밀히는 CPython에 대한 이야기입니다. CPython은 Python이라는 언어를 ..

Python 2020.06.03

-m 실행 옵션과 __name__

Python 관련 글들을 보다 보면 스크립트를 실행시킬 때 어떤 때는 python3 script.py처럼 실행시키고, 어떤 때는 python3 -m script처럼 -m 옵션을 사용해서 실행시킬 때가 있습니다. 차이는 무엇일까요? 전자는 script.py를 실행시키는 것이고, 후자는 script라는 이름의 모듈을 sys.path에서 찾아서 실행시키는 것입니다. sys.path에 대한 설명은 알쏭달쏭 Python import - sys.path을 참고하세요. 오늘도 간략한 예시를 들어서 알아보겠습니다. 1. 간단한 함수부터 아래와 같은 Python 코드를 만들고 있다고 가정해보겠습니다. 주어진 문자열 주위를 아름답고 화려한 *으로 감싸주는 코드입니다. import sys def print_with_bord..

Python 2020.05.28

venv는 내부적으로 어떻게 작동할까?

Python의 모듈 간 의존성 문제를 해결하기 위해서 virtualenv나 venv를 많이 사용하실 겁니다. 시스템에 설치된 모듈들과 virtual environment 내에 설치된 모듈들을 분리해주기 때문에 모듈들이 꼬일 걱정 없이 사용할 수 있어서 참 좋습니다. 개인적으로 저는 새 Python 프로젝트를 시작하면 venv와 git 초기화를 꼭 실행합니다. 그런데 가끔 내부적으로 어떻게 이 기능이 작동하는지 궁금할 때가 있습니다. 그래서 오늘은 venv가 어떻게 작동하는지 한번 알아보겠습니다. (virtualenv도 작동 방식은 거의 동일합니다.) 1. venv를 만들자 먼저 아래 명령으로 virtual environment를 만듭니다. python3 -m venv env 그럼 현재 디렉터리에 env ..

Python 2020.05.19

bad magic number in 'application': b'\x03\xf3\r\n': ImportError

자주 겪는 문제는 아니지만 종종 python에서 bad magic number in 'application': b'\x03\xf3\r\n': ImportError가 날 때가 있습니다. 이 에러는 python 2.x 대 버전으로 만들어진 *.pyc 파일을 python 3.x 대 버전으로 실행시키려고 할 때 발생합니다. "python main.py" 명령으로 main.py를 실행시킴. main.py는 다른 모듈들을 import 함. python 명령은 python 2.x 버전이고, 이 과정에에서 python 2.x 대에 맞는 *.pyc 파일들이 생성됨 python 2.x가 아닌 python 3.x를 써야했다는 생각이 떠올라서 "python3 main.py" 명령으로 다시 main.py를 실행시킴 bad ma..

Python 2020.05.19

알쏭달쏭 Python import - sys.path

Python으로 만들고 있는 프로그램이 커지기 시작하면 모듈화를 합니다. 이 기능, 저 기능을 모아서 하나의 파일로 합쳐서 모듈(*.py)로 만들지요. 모든 모듈들이 한 디렉터리에 있을 때는 아무 문제없이 행복합니다. 그러다가 조금 더 프로그램이 커지면 모듈들을 모아서 패키지(디렉터리)로 만들고 슬슬 문제가 시작됩니다. 멀쩡히 import 되던 모듈들이 찾을 수 없다며 import가 되지 않거나 , 엉뚱하게 동작하는 일들이 생기죠. 이것이 다 python의 sys.path 때문입니다. 1. sys.path 누구냐 넌 sys.path는 모듈을 import 할 때 모듈을 찾아야할 경로들을 저장해둔 list입니다. 예를 들어 sys.path가 ['directory_A', 'directory_B', 'direc..

Python 2020.05.15

함수의 인자를 특정 값으로 고정하기 - functools.partial

일반적으로 쓸 일이 많지는 않지만, 함수를 higher-order function 형태 (lambda, decorator 등 함수 자체를 하나의 객체로 취급하는 경우)로 쓰다 보면, 기존 함수를 재활용하는 경우가 왕왕 있습니다. 한 가지 예는 기존 함수의 특정 인자를 특정값으로 고정시키는 경우죠. 예를 들어, 아래와 같은 코드를 보겠습니다. def print_characters(char, repeat): print(char * repeat) print_characters('*', 10) ********** 별을 10개가 아니라 20개를 출력하고 싶다면? print_characters('*', 20) 그런데 왜인지 무조건 별을 20개 출력하는 함수를 만들고 싶어졌습니다. def print_character..

Python 2020.05.12

함수 이름으로 함수 호출하기

함수 이름을 알고 있을 때, 그 이름으로 함수를 호출하고 싶을 때가 있습니다. 예를 들어, 함수의 이름이 tokenize 일 때 이 함수를 어떻게 호출할 수 있을까요? 당연히 아래와 같이 호출합니다. tokenize() 너무나 당연하죠. 그런데 가끔 다르게 호출하고 싶을 수도 있습니다. 이렇게요. f = getattr(sys.modules[__name__], 'tokenize') f() 굳이 왜죠. 왜 이렇게 어렵게. 프로그램 실행 중 동적으로 함수 이름을 알아내고, 이 함수를 호출해야 할 때가 있습니다. 예를 들어 한국어 토큰의 단위는 뭐가 좋을까? 에서 tokenize_by_morpheme_jaso, tokenize_by_morpheme_char, tokenize_by_eojeol_jaso, toke..

Python 2020.05.05

Shell 명령의 결과를 받아오고 싶을 때

파이썬 코딩을 하다 보면 이미 필요한 기능이 리눅스 명령으로 존재할 때가 있습니다. 가끔은 리눅스 명령을 실행해서 결과를 가져오는 것이 편할 때가 있죠. 물론 이 방법은 해당 명령이 해당 시스템에 설치되어야 있어야 하기 때문에 이식성이 조금 떨어집니다. 하지만 적절히 필요한 곳에 쓴다면 개발 속도를 확 높여 줄 수 있습니다. 예를 들어 어떤 텍스트 파일이 몇 줄인지 궁금할 때가 있습니다. 파일을 열고, 줄 별로 읽어서 카운트를 할 수도 있지만, 리눅스의 wc 명령을 간편하게 이용할 수도 있습니다. 속도도 매우 빠르고요. import subprocess result = subprocess.run(['wc', '-l', 'wiki+namu.raw.txt'], stdout=subprocess.PIPE) res..

Python 2020.05.01

간편한 Progress Bar 모듈 - tqdm

큰 데이터를 다루다 보면 지금 프로세싱이 어디까지 처리됐는지 궁금할 때가 있습니다. 텍스트 파일에서 한 줄씩 읽어서 전처리를 할 때도 그렇고요. 데이터를 여기에서 저기로 옮길 때도 그렇고요. 시간이 너무 오래 걸리다 보면 '어딘가에서 무한루프를 돌고 있는 것은 아닐까', '코드를 잘못 짜서 한번 도는데 너무 오래 걸리는 것이 아닐까' 등등 많은 생각이 듭니다. 불안한 마음에 Ctrl+C를 확 눌러버릴까 유혹도 받지요. 자리를 잠시 비우기도 애매하고요. 꼭 자리를 비울 때 에러를 내고 죽으니까요. 가상의 상황을 가정해서 아래처럼 한번에 0.05초가 걸리는 작업을 100번 돌린다고 생각해보겠습니다. 이 경우야 5초면 끝나겠지만 큰 데이터를 다루다 보면 도대체 언제 끝날지 감이 안 올 때가 많습니다. 그리고 ..

Python 2020.04.26