Python

최근 수정 시각:

분류

파일:나무위키+유도.png   다른 의미의 Python에 대한 내용은 파이선 문서를 참조하십시오.

파일:나무위키프로젝트.png
이 문서는 나무위키 컴퓨터 프로젝트 · 나무위키 프로그래밍 프로젝트에서 다루는 문서입니다.
해당 프로젝트 문서를 방문하여 도움이 필요한 문서에 기여하여 주세요!


print('Hello world!')

TIOBE에서 선정한 프로그래밍 언어 월간 점유율 순위

[ 펼치기 · 접기 ]

1. Java

2. C

3. C++

4. Python

5. VB .NET

16.139%
+2.37% 증가

14.662%
+7.34% 증가

7.615%
+2.04% 증가

6.361%
+2.82% 증가

4.247%
+1.20% 증가

6. C#

7. PHP

8. JavaScript

9. SQL

10. Objective-C

3.795%
+0.28% 증가

2.832%
-0.26% 감소

2.831%
+0.22% 증가

2.334%
+2.33% 증가

1.453%
-0.44% 감소

2018년 7월 기준이며, 전년 동월 대비 변화 수치이다. 자세한 내용은 TIOBE에서 확인할 수 있으며, 기준은 다음과 같다.

''Life is short, You need Python.''[1]
인생은 짧다, 당신은 파이썬이 필요하다.

1. 소개2. 특징
2.1. 디자인 철학2.2. 높은 생산성2.3. 반복 가능한 객체2.4. 만능 언어
3. Python 2 vs 3
3.1. Python 2의 취약점3.2. Python 3
4. 구현체 종류
4.1. Stackless Python4.2. C 언어 확장, Cython4.3. C++ 구현, Pyston (프로젝트 중단)4.4. Python 구현, PyPy4.5. Java 구현, Jython4.6. .NET Framework 구현, IronPython4.7. JavaScript 구현, Brython
4.7.1. 자바스크립트로 컴파일 transcrypt
5. 멀티스레딩 문제
5.1. 멀티코어 프로그래밍 하기
6. GUI 프로그래밍
6.1. Tkinter
7. 라이브러리
7.1. 수학, 통계학, 과학, 공학, 빅 데이터7.2. 머신 러닝
8. 프레임워크
8.1. 웹 프레임워크8.2. 파이게임
9. 관련 팁
9.1. 개발 환경
10. 여담
10.1. 파이썬의 철학(The Zen of Python)

1. 소개[편집]

1991년에 발표된 인터프리터 방식[2]프로그래밍 언어. 공식 홈페이지 공식 깃헙 저장소

창시자는 귀도 반 로스음(Guido van Rossum). 네덜란드어 발음으로 '히도 판 로쉼'. 1989년 크리스마스 주에, 연구실이 닫혀있어서 심심한 김에 만들었다. 파이썬 서문마이크로소프트웨어와 한 인터뷰를 보면 알겠지만 사실이다. 기술자들은 심심할 때 항상 걸작이 나온다. 2000년에는 Python 2, 2008년에는 Python 3가 나왔다.

이름은 귀도가 즐겨 보던 영국의 6인조 코미디 그룹 몬티 파이선에서 따왔다고 한다. 지금 CPython 공식 GitHub 저장소를 보면 협업보조용 봇 이름들이 the-knights-who-say-nibedevere 같이 죄다 몬티 파이선과 성배의 배역들이다. 많은 파이썬 교재들에서 변수 이름을 spam, eggs로 짓는 등 드립을 친다. 직접적 관계는 없지만 42도 필수요소. 물론 사전적 의미를 생각 안 하는 건 아니라서 심볼마크가 모양이다.

문법이 매우 쉬워서 초보자들이 처음 프로그래밍을 배울 때 추천되는 언어이다. 오죽하면 파이썬의 별명이 '실행할 수 있는 의사코드(Executable pseudocode)'일 정도. 실제로도 미국 공과 대학교에서 컴퓨터 프로그래밍 입문 수업으로 파이썬을 많이 사용하기도 한다. 동시에 실사용률과 생산성도 높은 강력한 언어.

2. 특징[편집]

2.1. 디자인 철학[편집]

Perl의 '하나 이상의 해결법이 존재한다' 에 대비되는 '가장 아름다운 하나의 답이 존재한다' 를 기본으로 하고 있다. 이것은 남이 작성한 코드를 내가 읽고 이해해야 하는 경우 아주 절실히 느낄 수 있다. 이 원칙 하에 다음과 같은 철학을 지니게 되었다. The Zen of Python의 첫 세 항목이다. The Zen of Python에는 총 20가지 항목이 존재한다.

  • 아름다운 것이 추한 것보다 낫다.(Beautiful is better than ugly)

  • 명시적인 것이 암시적인 것보다 낫다. (Explicit is better than implicit)

  • 간결한 것이 복잡한 것보다 낫다. (Simple is better than complex)


따라서 다른 언어들의 코딩 스타일은 각자의 취향에 맞게 발산 진화하는 반면, 파이썬은 위의 철학들을 만족 시키는 하나의 스타일로 수렴 진화하는 성향이 있다. 실제로 C 계열의 언어에서 중괄호의 위치에 대한 논쟁은 거의 종교적 논쟁에 가깝다. 현재 한국에서 가장 많이 쓰이는 방식은 C언어의 창시자 Kernighan과 Ritchie의 K&R 스타일이다. 그러나 Eric Allman의 방식을 고수하는 사람들도 제법 많다. 이외에도 중괄호 위치를 정하는 다른 방법들이 있으며 자세한 내용은 http://gyumee.egloos.com/1306012에서 확인 가능. 그리고 흔치는 않지만 몇몇 사람들은 그냥 들여쓰기고 뭐고 다 무시하고 쭉 작성해놓기도 한다. 이런 성향은 다른 언어에는 없는 파이썬스러움(pythonic)이라는 독특한 개념을 낳게 되었는데, 복잡하지 않으면서 의미가 명확하고, 심플한, 파이썬의 철학을 따르는 것들을 지칭하는 개념이다.

이런 철학 때문에 문법이 굉장히 엄격한 편이다. 예를 들자면, 다른 언어에서는 해도 되고 안 해도 되는 들여쓰기가 이 언어에서는 의무로, 들여쓰기 자체로 하나의 코드 블럭이 된다. 코드 블럭을 명시적으로 표시하지 않아도 돼서 비주얼 적으로는 굉장히 깔끔한 반면 자유도를 제약한다는 평도 있다. 근데 어차피 들여쓰기는 하게된다.

코드에서 중괄호는 모아놓고 보면 굉장히 지저분할 뿐더러, 당장 처야하는 괄호가 2개나 되고, 괄호 하나라도 잘못 넣으면 블럭이 다 꼬여버리는 귀찮은 존재이지만(begin 과 end 혹은 end. 으로 구분해야 하는 파스칼에서 보면 중괄호만 해도 엄청나게 간결해 보이지만), 대신 블럭들을 이리저리 만질때는 매우 편리한 존재이다. 특히 C 코드를 종이에 출력해보면 중괄호 있고 없고의 가독성 차이가 의외로 크다. 파이썬에서는 이 중괄호를 들여쓰기로 대체하는데, 이게 블럭의 시작과 끝 지점을 찾는 부분에서 꽤 불편하다. 대신 괄호를 2개나 일일이 다 넣고, 잘못 넣지 않게 점검도 해줘야하는 수고가 없다는 엄청난 장점이 있다.

def factorial(x):
    if x == 0:
        return 1
    else:
        return x * factorial(x - 1)

이 들여쓰기 의무 규칙 때문에 소스 코드 들여쓰기에 탭(Tab) 문자를 사용하지 않을 것을 매우 강력히 요구한다. 문자는 사용자나 시스템의 설정에 따라 서로 다른 폭의 공백이 생긴다. 문제는 파이썬 인터프리터가 탭 문자 하나를 공백 1문자로 처리한다는 것이다. 탭 문자로 들여쓰기를 처리하면 자신과 다른 탭 설정을 가진 에디터에서 코드를 열어 볼 경우 코드 들여쓰기가 높은 확률로 망가져 버리고, 그걸 교정해보겠다고 들여쓰기에 공백 문자를 혼용하는 순간 해당 소스 코드는 사람이 고칠 수 없는 형태로(시각적으로는 블록이 맞지만 파이썬 인터프리터는 다른 블록으로 인식) 망가져 버린다. PEP-8에 명시된 공식 코딩 가이드에서는 스페이스 바공백 4문자를 넣기를 권장하고 있다.[3]

2.2. 높은 생산성[편집]

파일:xkcdpythonko.png


인터프리터 언어이면서 우수한 자료형과 다양한 모듈 등을 제공해 개발기간이 매우 단축되는 것이 특징. 'C언어로 2년동안 완성하지 못한 프로젝트를 파이썬으로 한달만에 해냈다'는 극적인 경험담이 있을 정도다. 당장 파이썬의 집합 자료형 같은 경우 C언어로 구현하려고 하면 머리가 아파온다. C언어와의 접착성도 좋기 때문에, 일단 Python으로 빨리 구현하고, 남은 시간에 속도에 병목이 되는 부분을 C로 전환하는 전략을 내세우고 있다. 버전이 올라가면서 Python 자체도 그리 느리지 않게 되었다.

참고로 저 만화는 파이썬 내에 이스터 에그로 삽입되기도 했다. import antigravity로 antigravity 모듈을 불러오면 나온다.영상

413화에서 로봇에게 영혼을 부여할 때도 사용한다 import soul

2.3. 반복 가능한 객체[편집]

파이썬의 가장 큰 특징 중 하나. 파이썬은 반복 가능한 객체(iterable)라는 강력한 기능을 제공한다. 이 객체는 집합, 문자열, 리스트, 튜플, 딕셔너리, 그리고 함수[4]까지도 반복이 가능하며, 이것을 for 구문에서 사용할 수 있게 해준다. 리스트와 튜플 등은 좀 편해지는 정도라 할 수 있지만, 함수의 값을 반복할 수 있다는 것은 큰 장점이다. 그 예로 n의 배수를 구하는 f(n) 함수가 있을 때,

def f(n):
    x = 1
    while 1:
        yield n*x
        x += 1

와 같은 함수를 만드는 것도 가능하다. 함수를 호출하고 나서도 함수가 완전히 끝나기 전까지는 지역 변수가 남아있으며, 함수가 끝나야 지역변수가 삭제된다. 따라서 함수를 호출할 때마다 x의 값이 증가한다. 이렇게 만들어진 반복 가능한 객체는 __next__ 함수나 next(객체)함수, 또는 for ... in 객체 와 같은 문법들을 이용하여 순서대로 값을 호출할 수 있다. 특히 제너레이터의 경우, 미리 만들어놓는게 아니라, 호출 될 때 반환값을 새로 만들어 반환하는 방식이기 때문에 메모리 관리 면에서도 이점이 있다.

2.4. 만능 언어[편집]

PyPI#라는 패키지 저장소가 2012년 구축되었다. 2018.2 기준 129,000여개의 패키지를 제공한다. 여기에 등록된 패키지들은 pip#를 통해 간단하게 내려받을 수 있다. 다만, PyPI가 최초, 최대의 패키지 저장소는 아니다.

Python으로 직접 만들었거나 또는 다른 프로그램의 Wrapper가 꼭 존재한다. 사실상 못하는 것이 없다. 웹 사이트 서버를 구현하려고 하면 Python Web Framework를 쳐보자(Django, Flask, Bottle 등). 기계학습 알고리즘을 쓰고 싶다면 python machine learning이라 검색하자(scikit-learn). 얼굴인식을 코드 몇 줄로 할 수도 있다(OpenCV). 기본적으로 설치되는 모듈인 tkinter 모듈을 이용하면 간단한 gui프로그래밍을 할 수 있다. 게임도 만들 수 있다(PyGame). 비주얼 노벨도 만들 수 있다. 비주얼 노벨 전문 툴 Ren'Py 참조.

물론 그렇다고 Python만 쓰는 것이 답은 아니다. 실행 속도(정확히는 CPython의 실행 속도)가 상대적으로 느린 편이라, 빠른 속도가 필요한 프로그램 작성에는 한계가 있다. 일반적으로 기계어로 컴파일하여 사용하는 C, C++보다는 당연히 느리고, Lua, JavaScript, LISP 계열 언어 등 동적 언어들을 전체를 주욱 놓고 비교해 봐도 속도가 빠른 편은 아니다. Python처럼 가상 머신 위에서 실행되는 Java, JavaScript 등의 언어들의 경우, 속도 문제를 극복하기 위해서 JIT 컴파일러를 도입했다. Python의 사실상의 표준 구현체인 CPython은 JIT 컴파일을 도입하지 않았고, JIT 컴파일을 도입한 별도의 구현체인 PyPy가 등장했다. 통계 분야 등 특정 분야에서는 R과 같이 그 분야에 특화된 언어를 사용하는 것이 더 편리할 수도 있다.

그리고 동적 타입 언어(dynamically typed language)라는 점이 큰 프로젝트에서는 단점으로 작용하여 자료구조 설계나 디버깅이 어렵다는 지적도 있다. 다만 "정적 타입 vs. 동적 타입" 논쟁은 서로의 장단점이 있으며 일종의 종교 논쟁으로 취급 받는다. 일례로 OCaml 같은 강력한 타입 인터페이스(Hindley-Milner, System F 등)를 가진 경우, 모든 타입 에러(!)를 컴파일 타임에 잡아낼 수 있는 반면에, 모든 버그가 타입 에러는 아니기 때문에 여전히 테스트 및 디버깅 과정은 필요하며, 타입 시스템으로 인한 부담 때문에 빠른 구현에는 부담이 될 수 있다. 반면에 동적 언어는 빠른 구현의 이점이 있지만 타입 에러가 많이 나는 특징이 있다. Python으로 parser를 많이 작성해봤다면, 십중팔구 읽은 숫자를 string으로 저장했다가 나중에 연산을 했더니 연산이 불가능하다면서 에러가 나거나 이상한 결과가 나온 경험이 있을 것이다.

그러나 커버리지가 높은 테스트 세트로 어느 정도 커버 할 수 있으며 최근의 추세와 부합하는 방식이기도 하다. 또한 Python 3.5부터는 Type Hints를 이용해서 변수가 가질 수 있는 타입을 지정할 수 있게 되었다. 성능 향상에 도움은 안되지만 가능한 오류를 쉽게 찾아낼 수 있으며 PyCharm과 같은 IDE 프로그램을 이용하면 향상된 Code Completion의 도움을 받을 수 있다.

특정 언어를 어떻게든 돌아가게 짜는 것은 노가다를 배우는 것이라면, 프로그램의 설계는 건축가가 거대한 빌딩을 설계하는 작업이라고 할 수 있다. 1~2층 정도의 작은 집은 오로지 노가다로 해결한다고 해도, 부르즈 할리파를 이런 식으로는 지을 수 없다. 적절한 자재, 하중을 지탱할 수 있는 구조, 외력 등을 고려해서 설계해야 한다. 이렇게 하기 위해서는 알고리즘과 자료구조, 아키텍처 등의 공학적 지식과 경험이 있어야 하며, 제대로 훈련된 프로그래머와 단순 코더가 짠 코드는 생산성, 탄탄함, 버그 발생률, 확장 가능성에서 큰 차이가 난다.

빠른 아이디어 구현이 생명인 연구소에서 각광을 받고 있고, 한국 밖에서는 당당한 주류 언어로 대우받고 있다. 인스타그램, 유튜브, reddit 등이 Python을 주로 쓰고 있다고 알려져 있으며, 외국의 구인 사이트에도 Python을 할 줄 아는 사람에 대한 수요가 많다. 컴퓨터 관련이 아닌 이공계 전반에서 많이 쓰이는 MATLAB은 오픈소스가 아니라는 점이 최근 추세와 맞지 않아 입지가 좁아지고 있다. 그러나 MATLAB의 다양한 상용 툴 박스에 비하면 아직 미비한 부분이 있다. 대표적인 예가 Simulink이다. 현재 Python이 MATLAB에서 당분간 절대 대체하기 불가능할 것으로 보이는 기능은 Simulink라는 MATLAB의 강력한 GUI 기반 모델링 툴 박스로, 현존하는 상용/공개 소프트웨어 중 FMI(Functional Mock-up Interface)의 수단으로서도 가장 강력한 툴이다. MATLAB은 이를 이용한 직관적인 시스템 모델링 및 제어기, 추정기 로직 설계가 가능하다. 그리고 이를 C로 포팅하여 임베딩을 위한 제어코드를 만들 수 있고 각종 제어기 프로토타이핑 컨트롤러에 올리는 것이 가능하다. 제어기 로직의 설계와 실험, 검증에 있어서 fast prototyping이 필요한 경우라면 Simulink의 강력함을 대체할만한 opensource software가 없는 것이 현재의 상황이다. 따라서 시스템과 제어기 내부의 로직을 모델링, 연구하고 빠르게 시험하는 분야는 아직 Python이 대체하기 어려운 부분이라고 할 수 있다. 때문에 제어 분야의 엔지니어들은 Python이 언젠가 상용 공학 프로그램을 상당수 대체할 거라는 소리를 믿지 않는다. 현재 오픈소스 프로그램 중 GUI 기반 모델링 및 Functional Mock-up Interface를 지원하는 프로그램은 OpenModelica등의 몇몇 프로그램이 있고 Simulink 수준의 강력한 프로그램은 없으며 당분간 대체가 불가능할 것으로 보인다. Simulink 툴 박스는 기업 용으로 구매하면 기본 toolbox가 1 copy에 천만 원 단위, 각종 전기, 전자, 기계, 유압, 항공 등에 관련한 라이브러리는 추가로 유료로 판매한다. 거기에 C로 포팅 해주는 모듈도 역시 개별적으로 추가 구매해야 한다. 만약 오픈소스 소프트웨어로 Simulink를 대체하고자 한다면 현재로서는 FMI 기능 및 C 코드로의 오토코딩 모듈이 있어야 할 것이다. 게다가 패키지 설치를 참 더럽게 이상하게 만들어 놨다. MATLAB과 같은 목적의 Python 패키지인 NumPy는 모종의 계약을 통해 문법과 함수 등의 많은 부분에서 MATLAB 함수와 호환되게 수정해 버렸고, 안 그래도 꽤 쓰였던 NumPy는 더욱 사용자가 늘어나고 있다. Python의 경우는 지원 라이브러리의 대부분이 오픈소스이기 때문에 저장소에서 그냥 커맨드 라인(pip install 패키지) 한 줄로 필요한 거의 모든 패키지를 설치해서 쓸 수 있다. 물론 PyQt 같은 예외도 존재한다. CG 업계에서도 사실상 표준으로 사용되는 스크립트 언어이다. MEL, MAXScript 등 툴별로 자체 스크립트 언어들이 난립하고 있었는데, 현재는 Python 스크립팅을 주력으로 밀고 있다.

대학교 프로그래밍 교육은, 예전에는 한국을 포함하여 대부분의 학교에서 C, C++나 Java 같은 실제 회사에서 많이 쓰는 언어 위주로 수업을 개설했으나, 미국 대학들은 개론 수업 언어를 Python으로 옮겨가는 추세다. UC 버클리 컴퓨터과학 개론수업인 CS 61A 를 인터넷 강의로 들어보자! 참고로, 연세대학교,[5] 카이스트, 성균관대학교[6], 부산대학교, 국민대학교,[7] 서강대학교,[8] 상명대학교, 인천대학교, 한양대학교 ERICA 캠퍼스, 세종대학교, 경희대학교 소프트웨어융합학과에서는 프로그래밍 개론 수업을 Python으로 진행한다.

게다가 요즘은 프로그래밍 언어와 프레임웍의 춘추전국시대라고 할 수 있을 만큼 매우 많은 새로운 언어와 프레임웍이 등장하고 있으며, 아예 폴리글랏(Polyglot[9]) 프로그래밍이라는 용어가 등장하는 시대다. 당장 구글만 해도 C++, Java, Python을 골고루 섞어서 쓴다고 알려져 있으며, 게임도 메인은 C++로 작성되었지만 스크립팅은 Python이나 Lua로 된 경우(시드 마이어의 문명, WOW 등)를 매우 쉽게 찾아볼 수 있다. 따라서 필요하다면 프로그래밍 언어를 가리지 않고 매우 능숙할 수 있게 사용할 수 있도록 공부해야 하며, 알고리즘, 디자인 패턴, 테스트 기법, 동시성 프로그래밍(멀티스레드, 멀티프로세스) 등의 필요한 지식을 훤하게 꿰고 있어야 제대로 된 프로그래머/개발자가 될 수 있다.

마지막으로, Python이 배우기 쉽다는 것은 어디까지나 프로그래밍 입문자의 입장에서 다른 언어에 비해 비교적으로 쉽다는 뜻이지, 깊게 파고 들어가거나 특유의 '파이썬스러움(pythonic)'한 코딩을 하려면 생각보다 신경쓸 것도 많고 동적 언어에 익숙해져 있어야 한다. 하여튼 프로그래밍 자체를 마냥 쉬운 것으로 생각하다면 큰 코 다친다. 프로그래밍을 쉽게 할 수 있는 것과 좋게 하는 것에는 큰 차이가 있으며, 좋은 프로그래밍을 하는 것은 프로그래머의 역량에 크게 좌우된다.

Python으로 할 수 있는 것들을 모아 놓은 곳도 있다! https://github.com/vinta/awesome-python

3. Python 2 vs 3[편집]

Python 2.5.6 이하

print 'Hello world!'

Python 3.0.0 이상

print('Hello world!')

파이썬 3부터 print가 함수가 되었다.https://docs.python.org/2/whatsnew/2.6.html Python 2.6.0 ~ 2.7.14까지는 두가지 스타일을 모두 쓸 수 있다.

결론부터 말하자면 이제는 Python 3.

Python 2와 Python 3는 비슷한 부분 만큼이나 호환되지 않는 부분도 많아 학습, 구현을 목표로 할 때 둘 중에 하나를 선택해야 하는 문제가 발생했다. Python 2부터 대중화가 시작된 만큼 누적된 코드들은 Python 2를 기반으로 한 코드가 매우 매우 많았다. 그러나 Python 2는 2.7에서 Python 3와 최대한 호환되도록 언어를 보완한 이후로 더 이상 기능 추가가 없다. 설상가상으로 2020년까지 bugfix만 이루어진 후 지원을 종료할 예정이다.# Python 3로 갈아타게 하려는 계획은 Python 3가 2008년, Python 2.7가 2010년에 나왔다는 걸 고려하면 굉장히 더디게 이루어진 편이다. 나무위키의 이 문서도 2016년까지 Python 2.7가 여전히 대세라고 나와있는 것을 생각해보면 그 속도를 느낄 수 있다.

Python 3.4 부터 Python 2에 비해 강력한 기능들을 제공하기 시작했고, 그즈음 해서 대부분의 파이썬 패키지들은 Python 2, 3 겸용으로 제공되거나, 아예 Python 3 전용으로 제공되고 있다. 2016년 들어서 대표적인 리눅스 배포판인 우분투의 버전 16.04부터 기본 파이썬 버전이 3.5로 바뀌었고, PyPy에서도 Python 3.5 버전을 목표로 개발을 시작했다.

3.1. Python 2의 취약점[편집]

파이썬 2.7 버전 이하에 사용자의 입력을 string형으로 받는 input() 함수가 존재한다. C 언어 등을 접해온 초보자들은 scanf류 함수겠거니 하고 사용하게 된다. int든 str든 bool이든 뭐든 잘 받아서 꽤나 편하기 때문에 치명적인 실수를 하나 저지르는데...

신뢰할 수 없는 소스의 입력을 이 함수로 보내면 큰일 난다. input() 함수는 엄청 큰 권한을 갖고 있다. 현재 모듈에 로드된 모든 name에 접근할 수 있고 그것이 함수이면 실행할 수 있다는 것. 만약에 sys 모듈이 메인에 로드되어 있고 os.system[10]을 이용하면 다음과 같은 짓을 할 수 있는 것이다.

'>>>'가 붙은 라인은 유저가 키보드로 입력한 라인, 그러지 않은 라인은 코드라고 하자. 그러면,

input()
>>> sys.modules['os'].system("rm -rf /")


위와 같이 실행자가 원하는 rm -rf / 같은 명령어가 포함된 코드를 실행할 수 있다. 물론 혼자서 사용할 스크립트라면 상관없다. 왜냐면 털어봤자 내 계정을 터는 게 되어버리니까. 그러나 이 스크립트가 다른 유저가 실행할 때 내 권한을 취득하도록 설정되었다면(=setuid bit가 설정되었다면) 어떨까? 사용자는 비밀번호 없이 스크립트를 실행하는 것만으로 어렵지 않게 내 계정의 권한을 획득하게 된다! 마찬가지로 netcat 등으로 외부 네트워크에서 들어온 입력을 input()이 포함된 파이썬 스크립트에 흘려보내면 비슷하게 위험한 상황이 발생할 수 있다.

그래도 .py 파일에 sys를 로드하지 않으면 괜찮지 않을까?

del sys
input()
>>> __import__('os').system("rm -rf /")

물론 소용 없다. 파이썬은 모듈을 동적으로 로드하는 __import__를 빌트인 함수로 지원하기 때문이다.

그렇다면 input()을 받아올 때만 __import__ 같은 수단을 모두 막아버리면 되지 않을까?

__builtins__를 초기화 시켜서 __import__를 비롯한 빌트인 함수를 없애보자. 그러면 str, bool, int같은 기본형 밖에 못 받도록 제약을 걸 수 있을 것처럼 보인다. 하지만...

__builtins__ = {} # 모든 기본 함수들을 없애버린다.
input()
>>> [x for x in ().__class__.__base__.__subclasses__() if x.__name__ == 'catch_warnings'][0]()._module.__builtins__["__import__"]("os").system("rm -rf /")

참고로 이 방법은 3.X에서 되지 않는다. 3에서는 []가 반복 가능한 객체를 리스트로 바꾸는 기능이 아닌 데다가 그대로 반복 가능 객체가 든 리스트를 반환하기 때문이다. 따라서 반복 가능 객체를 리스트로 변환하도록 list(x for x in ().__class__.__base__.__subclasses__() if x.__name__ == 'catch_warnings')를 써야 하는데, 빌트인 함수를 삭제해 list 함수가 실행되지 않고, (x for x in ().__class__.__base__.__subclasses__() if x.__name__ == 'catch_warnings').__next__()._module.__builtins__["__import__"]("os").system("rm -rf /")와 같은 방법으로 해야 한다. 물론 그래봤자 3에서는 문자열로 받아 실행되지는 않고, 하고 싶으면 따로 실행해야 한다.

위와 같은 변태적인 방식으로 ()(빈 튜플)의 속성을 따라가면서 빌트인 함수를 복원한다. 이후에 복원한 빌트인 함수로부터 __import__ 함수를 가져와서 똑같은 일을 할 수 있다. 이것은 공격 벡터 하나일 뿐, 저런 방식을 어떻게 막아도 잠재적인 수많은 공격 벡터에 일일이 대응할 수는 없다. 스트링으로부터 코드를 받아서 실행하는 프로그램은 어떤 식으로 막으려 해도 결국 뚫릴 수밖에 없다. 정말로 네트워크의 스트링으로부터 eval을 해야 하는 경우에 OS 커널 단에서 설계된 sandbox 환경을 이용하도록 해야 한다.

그래도 로컬 컴퓨터에서 터미널 입력에만 거의 사용되는 input()함수는 낫지만, 초보자들이 파싱할 때 eval, exec을 쓰는 경우 매우 위험하다. 저 함수들은 인자로 받은 string을 코드로써 실행하는데, 이 경우 네트워크에서 얻어온 string을 집어넣도록 짜여있는 경우가 꽤 있기 때문이다. 위에 있는 테크닉을 이용하여 공격 스트링을 만든 뒤 네트워크 소켓을 통해서 흘려보낸 뒤 프로그램 eval의 인자로 넘기면 컴퓨터의 제어권을 뺏는 것은 시간 문제가 된다.

가장 좋은 방법은 신뢰할 수 없는 입력을 받거나 가공할 때는 input, eval, exec을 이용하지 않는 것이다. 따라서 단순히 인풋을 받아야 하는 상황에서는 웬만하면 input()을 버리고, string line을 받는 raw_input()(Python 2.x 한정)을 사용하거나 sys.stdin.readline()을 이용하도록 하자. Python 3부터는 input이 이전의 raw_input을 대체했다.

3.2. Python 3[편집]

사용자가 늘다 보니 여러 단점들이 지적되었는데, 과감하게 하위 호환성을 포기하고 'Python 3000'이라는 코드명으로 개발하기 시작하여 발표된 버전이다. 내부적으로는 많이 변했다고 하는데 겉보기에는 별로 변한 것 같지 않다는 것이 함정. 그러나 소소한 부분에서 문법과 기본 라이브러리에 차이가 있어 호환이 되지 않는다. 2to3이라는 python2를 python3로 바꿔주는 컨버터가 있어서 전부 갈아 엎어야 하는 수고는 덜 수 있다.

Python을 실제로 사용하게 되면, 구현에 필요한 기능을 지원하는 여러 패키지를 받아서 설치해 사용하게 된다. Python 2.x vs Python 3.x에서 선택은 주로 "내가 사용하기 원하는 패키지가 동작하는 환경"에 따라서 선택하게 된다.

Python 3.x 부터는 C++, Java, 액션스크립트 등처럼 내부적으로 모든 문자열을 유니코드로 처리한다. 덕분에 창조(3번 항목)처럼 변수나 함수 이름을 한글로 정할 수도 있게 되었다.

이름 = "홍길동"
나이 = 17
출력 = print

출력('{} {}'.format(이름, 나이))


예를 들면 이런 식이다.

문제는 유니코드 문자열의 한 글자가 플랫폼 및 빌드 옵션에 따라 무조건 2바이트 또는 4바이트를 차지한다는 것. Python 2.x은 기본 문자열이 바이너리 문자열로 처리되기 때문에 한 글자가 1바이트만 차지한다. 하지만 Python 3.x는 기본 문자열이 항상 유니코드이고, UCS-4를 모두 지원하기 위해 문자 당 4바이트를 할당하는 "wide" 빌드의 Python 3.x는 100MB 길이의 아스키 문자열을 위해 400MB의 램을 사용한다. 따라서 문자열 처리에서 메모리가 낭비될 뿐만 아니라 처리 시간도 늦어져 성능이 떨어지는 것은 당연지사. 2.x 코드를 3.x에서 돌렸는데 많이 느리다면 문자열과 관계된 문제일 가능성이 높다.

이런 문제를 해결하기 위해, Python 3.3 버전 이후부터는 문자열 객체에서 가장 많은 공간(바이트)을 차지하는 문자를 기준으로 각 문자가 차지할 공간을 정하도록 변경되었다. 따라서 문자열에 아스키 문자만 포함된다면 각 문자가 1바이트씩만 차지하므로 더 이상 이런 문제가 생기지 않는다. 이런 경우는 심지어 유니코드임에도 Python 2.x의 유니코드 문자열보다 적은 메모리 공간을 차지할 수도 있다! 또한 UCS-4를 모두 지원하는 "wide" 빌드와 UCS-2만 지원하는 "narrow" 빌드의 구분도 사라졌다. 하지만 크기가 변경될 때 그 만큼 속도가 느려지니 장단점이 있다.

4. 구현체 종류[편집]

보통 말하는 Python은 C로 구현되었으며, 다른 구현체와 구분하여 언급할 때는 CPython이라고 표기한다. https://hg.python.org/cpython/file/tip 또는 https://github.com/python/cpython에서 소스 코드를 열람해볼 수 있다.

Stackless Python은 CPython에서 C 스택을 없앤 것이다.

Cython은 파이썬 소스 코드를 C 언어 코드로 변환하여 컴파일한다.

PystonC++로 구현되었다.

파이썬 자체로 구현된 PyPy도 있다. Pyston과 PyPy는 JIT가 구현되어 있다.

Java로 구현되어 Java Virtual Machine 위에서 돌아가는 JythonC#으로 구현된 .NET Framework 위에서 동작하는 IronPython이 있다.

Jython과 IronPython은 가상머신에서 동작하는 구현체이다. 시작부터 JVM 또는 .NET CLR 위에서 동작하는 Python 구현체를 도입하는 경우는 매우 드물다. 기존에 Java나 .NET Framework에서 개발되어 운영되던 프로그램이나 시스템이 존재하고, 이 환경 하에서 Python의 간결하고 편리한 기능과 높은 생산성을 도입하고자 할 때 사용된다.

Jython과 IronPython은 둘 다 CPython에 비하면 실행 속도가 매우 느리며, Jython은 경우에 따라서 심각할 정도로 많이 느리다. 따라서 주요 기능을 수행하는 데에는 문제가 있지만, 보조 기능에서 사용하면 번거로운 작업들을 매우 손쉽게 Python 스크립트로 Java, .net Framework의 자원을 그대로 끌어다 써서 할 수 있기 때문에 개발 공수와 편리함에서 큰 장점이 있다.

JavaScript로 구현한 BrythonSkulpt도 있다.

한편 중국에서는 Chinese Python이라는, 중국어 문법으로 한자를 쳐서 돌아가는 언어를 독자 개발했다.

4.1. Stackless Python[편집]

http://stackless.com/

파이썬의 표준 구현인 CPython은 이름 그대로 C로 만들어져 있는데, 파이썬 프로그램의 함수 호출 스택(Call stack)을 구현할 때 그만 C의 호출 스택[11]에 그대로 얹어가도록 구현되고 말았다. 때문에 파이썬에서 얼마나 메모리를 많이 쓸 수 있느냐에 관계없이 C 호출 스택을 꽉 채우는 순간 그대로 스택 오버플로우 에러가 뜨게 되어버렸고[12], 파이썬 프로그램의 호출 스택, 즉 프로그램의 실행 흐름을 CPython 스스로 제어할 수가 없게 되어 코루틴 등의 실행 흐름을 제어하는 언어 기능을 쓸 수 없게 되고 말았다.

Christian Tismer라는 개발자는 이 문제를 타파하려면 "CPython 소스코드를 수정해서[13] C 스택을 쓰는 부분을 전부 들어내고 새로 호출 스택을 짤 수밖에 없다"고 생각했고, 그것을 실제로 실행에 옮긴 것이 Stackless Python이다. 이름의 Stackless는 그래서 사실 C 호출 스택이 없다는 의미. Stackless Python은 스택 오버플로우 에러가 덜 난다는 사소한 장점(...)[14] 외에도, 스스로 제어할 수 있는 자체적인 호출 스택을 갖고 있기 때문에 마이크로쓰레드[15]코루틴 같은 기능들을 쓸 수 있게 됐고, 덕분에 쓰레드도 고자고 코루틴도 안되는 CPython에 비해 동시성 처리에서 훨씬 강력한 이득을 낼 수 있게 됐다. CPython도 3.4 버전 이후로 코루틴을 지원한다. 아래 멀티쓰레딩 섹션 참조.

다만, 앞서 말했듯이 CPython을 개조한 것이기 때문에, 파이썬의 버전이 올라갈 때마다 개조한 코드가 이상없이 동작하는지 항상 확인해야 하고, 이 기능이 운영체제나 하드웨어에도 영향을 받는 까닭에 심하면 각각의 운영체제나 CPU별로 개발을 따로 해야 하는 피곤한 작업을 Python이 망할 때까지 해야 하는 지겨운 길을 걷게 되는 것이었다. 그래서 실제로 한동안 Stackless Python의 개발이 잠시 중단된 일도 있었을 정도.

그런 와중에 PyPy 리드 개발자 Armin Rigo가 "C 호출 스택도 어차피 메모리에 있잖아? 그러면 그걸 'memcpy()'로 통째로 복사하고 덮어 씌우면 호출 스택을 저장하고 복구하는 거 아냐?"라는 실로 마개조스러운 아이디어를 내놓는데, Christian Tismer가 여기에 매우 깊은 감명을 받고 Armin Rigo와 함께 구현한 결과 greenlet이라고 하는 import만 하면 코루틴을 쓸 수 있는 모듈을 만들어내기에 이른다. 같은 걸 구현하려고 언어 인터프리터 자체를 뜯어 고치는 수고에 비하면 놀랄 만큼의 노력 절약이 아닐 수 없다. 다만 이 짓을 제대로 구현한 Stackless Python에 비하면 아무래도 성능이 딸리기 때문에 정말 절실하게 성능이 필요한 EVE 온라인과 같은 경우엔 Stackless Python을 쓴다.

하지만... Armin Rigo와 Christian Tismer는 지금 둘 다 PyPy를 만들고 있고, PyPy는 자체 스택을 쓸 수 있는 Stackless 모드의 JIT 컴파일러를 만들어낼 수 있다.

4.2. C 언어 확장, Cython[편집]

싸이썬 Psython
Python의 속도를 높이고자 아예 C언어로 변환하여 컴파일하는 방법을 택한 패키지. 파이썬의 문법을 확장하여 정적 타입 선언 기능을 넣어, 기존의 C 코드를 쉽게 접착할 수 있도록 만들었다. Python C API를 이용하여 C 코드를 직접 접착하는 기존의 방식보다 훨씬 사용하기 쉽고, C언어로 변환되어 컴파일 된다는 점 때문에 ctypes로 덧씌우는 것 없이 네이티브 코드(*.so, *.dll)를 직접 사용할 수 있다. 이것을 사용하면 적게는 열 배 정도에서 많게는 천 배 이상까지 속도 향상을 경험할 수 있다.

C를 모르는 상태에서 Cython을 사용하는 것이 아예 의미가 없는 것은 아니지만, C와 Python 둘 모두에 익숙할 때 Cython을 가장 효과적으로 쓸 수 있다. 고성능이 필요하면 일단 코드 수정이 불필요한 PyPy를 시도하고, 그걸로는 만족스럽지 않을 때 외부 라이브러리를 도입해 보고, 그걸로도 부족할 때 고려해보자. Cython의 대안으로는, SWIG, CFFI(C Foreign Function Interface), pybind(C++ 전용) 등의 도구들이 있다.

참고로, PyPy도 Cython에 크게 밀리지 않을 정도로 속도가 빠르고, PyPy를 사용하여 실행했을 때 속도 향상이 별로 없다면 Cython을 사용하여 C로 변환해도 상황이 비슷한 경우가 많다. Cython을 사용하여 속도 향상 효과를 얻고자 한다면, 파이썬 코드를 바로 실행할 수 있는 PyPy를 사용하여 속도를 미리 체크해보는 것이 유용한 방법이 될 수 있다.

4.3. C++ 구현, Pyston (프로젝트 중단)[편집]

Pyston은 LLVM 컴파일러를 사용한다. Pyston은 JIT(just-in-time) 컴파일러를 내장하여 반복되는 소스 코드를 빠르게 실행할 수 있다.

2014년 4월 프로젝트가 시작되었으며, Python 2.7 호환, x86 64비트 플랫폼을 목표로 개발 중에 있다. Dropbox Tech Blog - Introducing Pyston: an upcoming, JIT-based Python implementation (April 3, 2014)

Pyston은 C++로 작성되어졌다. Technical overview · dropbox/pyston Wiki · GitHub (1 Sep 2016)

우분투에서만 테스트되고 있다. 그러다가 2017년 1월 31일부로 Dropbox에서 공식적으로 스폰싱을 종료했다. Pyston 0.6.1 released, and future plans (January 31, 2017) 메인테이너가 Dropbox 직원인데 더 이상 참여를 못하는 사실상 프로젝트 중단이다. 직후 프로젝트 리더였던 Kevin Modzelewski는 퇴사하였다.

성능은 상당히 훌륭한 편이었으나, CPython과의 호환성을 오랫동안 맞추지 못했고, 프로젝트가 시작됐을 때와 다르게 Dropbox의 코드가 Go랑 Python3로 많이 이전된 것이 원인으로 보인다(즉, 굳이 투자하면서 개발을 지속할 이유가 없는 상황). 또한 곧 Python2 버전이 공식적으로 지원이 중단될 예정이라서 완전하게 돌아가게 되는 시점(이조차 아무도 알 수 없었다)에서 이 프로젝트의 의미가 많이 퇴색될 수밖에 없었던 것.

DropboxPyston에서 PyPy로 옮겼다가 현재는 Go를 쓰고 있다. Dropbox Tech Blog: Open Sourcing Our Go Libraries (July 1, 2014)

https://github.com/dropbox/pyston

4.4. Python 구현, PyPy[편집]

파일:나무위키상세내용.png   자세한 내용은 PyPy 문서를 참고하십시오.

본격 Python으로 직접 구현되는 Python. 언뜻 보면 CPython보다 느릴 것 같지만 실제로는 더 빠른 실행결과도 보여주는 흠좀무한 녀석이다.

4.5. Java 구현, Jython[편집]

Jython은 Java로 구현되어 JVM 위에서 실행된다. CPython이 C언어와 결합성, 접착성이 좋은 것처럼 Jython은 Java와 결합성이 대단히 좋으며, 실제로 Java 진영의 메이저 업체인 Oracle, IBM 등에서도 자사 제품에 Jython을 내장하여 스크립팅 기능을 제공하고 있을 정도다.

Jython은 JVM 위에서 실행되며, Python Module이 제공하는 API는 물론이고, JDK가 제공하는 모든 API를 그대로 사용할 수 있다. 오히려 pycrpyto와 같이 C언어로 구현된 CPython 모듈은 Jython에서 사용할 수 없다. 그러나 일단 Java Class라면, 설령 JNI로 되어있어서 C로 작성된 동적 모듈(*.dll, *.so 등)을 사용한다고 해도 Jython에서 사용하는데 아무런 제약이 없다. 또한 JVM위에서 실행된다는 점 때문에 CPython의 GIL이 이식 되지 않았으며, CPython이 멀티스레드에서 보이는 단점이 Jython에는 존재하지 않는다. threading, threadsafety 등의 Python에서 제공하는 멀티스레드(락, 동기화 관련) 기능이 마음에 들지 않으면 java.util.concurrent에서 제공하는 Java API를 사용하면 된다!

4.6. .NET Framework 구현, IronPython[편집]

Microsoft .NET Framework의 가상머신인 CLR 상에서 구현되고 이 위에서 동작하는 Python이다. 정확히 말하면 이들 동적언어를 CLR위에서 구현하기 위한 DLR 이라는 프레임워크 기반이다. 제작자 Jim Hugunin#Jython의 제작자이며, NumPy의 전신인 Numeric 라이브러리의 제작자이기도 하다. 따라서 당연히 .NET Framework 환경에서 제작된 DLL과 결합성이 매우 좋다. Jython과 마찬가지로 병렬 프로그래밍 환경에서 GIL 때문에 고민할 필요가 없다.

자매품으로는 C#로 작성된 모듈을 마치 파이썬 모듈처럼 임포트해서 쓸 수 있는 Python for .NET이 있으며 이 경우에는 CPython 위에서 돌아간다.

4.7. JavaScript 구현, Brython[편집]

JavaScript로 구현되었고, JavaScript를 대신하여 웹 브라우저에서 스크립트 형태로 Python을 실행할 것을 목적으로 하는 'Brython'이 있다. Python3를 구현했으며, 다음과 같이 script 태그의 type을 text/python으로 지정하여 실행할 수 있다.

<!DOCTYPE html>
<html>
<head>
	<title>Brython</title>
	<script src="brython.js"></script>
</head>
<body onload="brython()">
	<input id="zone"><button id="mybutton">click!</button>

	<script type="text/python">
		from browser import document, alert

		def echo(ev):
			alert(document['zone'].value)

		document['mybutton'].bind('click', echo)
	</script>
</body>
</html>

4.7.1. 자바스크립트로 컴파일 transcrypt[편집]

홈페이지

타입스크립트와 비슷한 방식으로 파이썬 코드를 자바스크립트로 컴파일해서 일반적인 자바스크립트와 혼합하여 사용할 수 있게 해준다. (Ex. 파이썬 + jQuery)

5. 멀티스레딩 문제[편집]

파이썬은 멀티스레딩을 지원하기 위하여 GIL(Global Interpreter Lock), 즉 전역 인터프리터 락을 도입하여 사용하게 되었다. 따라서, python 스레드 10개를 만들어도 실제 Pthread/윈도우 스레드가 10개가 만들어지긴 하는데, GIL때문에 개중 동시에 하나밖에 안돌아가는 기이한 구조를 갖고 있다. 물론, 내부적으로 IO작업이 있을 시 바로 다른 스레드로 문맥 교환을 해주고, 바이트 코트를 100번 실행한 다음에는 인터프리터 차원에서 다른 스레드로 교체 해주므로 동시 작업 비슷한 효과가 난다. 이것은 구현이 매우 쉬워지고 빠른 개발을 할 수 있다는 장점이 있으나, 다중 코어 CPU가 보편화된 2006년 이후에는 다중 코어를 제대로 활용하지 못하는 구조적인 문제 때문에 성능에서 밀린다는 평가를 받게 되었다. 만일 특정 프로그램에 순진하게 CPU 코어를 2개 이상 동원하려고 할 경우, 뮤텍스(MutEx), 즉 한 스레드에 여러 개의 CPU가 연산을 행하여 내부 정보를 오염 시키는 것을 방지하는 역할을 맡는 GIL이 병목 현상을 일으켜 코어 하나를 쓸 때보다 오히려 성능이 크게 저하된다는 것. 구글 내부에서 이미 가루가 되도록 까인 부분이다. Watch Mindblowing Python GIL - Tech Talks recorded by Carl Karsten 아카이브 #1 #2 #3

이런 문제점 때문에 파이썬에서 병렬 처리가 필요할 때는 다중 스레드가 아닌 다중 프로세스로 GIL을 우회하는 방식을 사용한다. 2008년 이후에 multiprocessing이라는 모듈을 제공하는데 이 모듈은 자식 프로세스를 만드는 방향으로 다중 코어 사용 시 성능의 향상을 꾀하고 있다.

단, CPU 부하가 큰 작업을 돌리는 것이 아니면 GIL을 체감하기는 생각보다 쉽지 않다. 다중 스레딩으로 CPU의 여러 코어를 최대한 이용하고 싶은 경우에는 GIL가 굉장히 아쉬운 이슈지만, CPU를 별로 쓰지 않거나 I/O가 주가 되는 작업은 유의미한 성능 차이가 없다. 게다가 어설프게 코어 몇개 깔짝깔짝 이용해서 계산하는 것보다는 그냥 C언어로 모듈을 짜서 붙이는 게 더 빠르다. 즉, python에서 CPU를 많이 먹는 부분은 C 모듈을 짜서 붙이거나, 이미 C 모듈로 짜여있는 라이브러리를 사용하거나(Numpy, Scipy 등), 필요하다면 multiprocessing 모듈을 이용하여 멀티코어를 활용하는 편. 그 이상의 CPU-heavy한 작업은 처음부터 C, C++로 짜는 게 맞다.

자세히 알고 싶다면 다음 링크들을 참조.(너무 오래된 링크들이라 차라리 인터넷 검색해서 최근 글들을 보기 바란다.)


하지만 대규모 연산의 멀티코어의 성능 향상을 보기 위한 것 말고도, I/O가 주가 되는 작업(즉, 여러 개의 I/O 이벤트를 기다리는 것)을 위해서 멀티스레드를 사용하는 경우가 많고,[16] 이런 경우에도 복잡한 동기화를 해야 하는 멀티쓰레딩을 사용하는 건 낭비이다. 왜냐하면 디버깅도 힘들 뿐만 아니라, 실제로는 I/O를 위해 기다리는 시간이 실제 I/O가 발생했을 때 필요한 처리 작업을 수행하는 시간보다 월등히 긴 경우가 많아 여러 개의 스레드를 관리하기 위한 자원만 낭비하는 꼴이기 때문이다.

따라서 GoErlang 같은 최근의 프로그래밍 언어들은 코루틴이란 개념을 도입해[17] 이러한 "event multiplexing"을 싱글스레드로도 구현할 수 있게 하고 있다. 특히 멀티쓰레딩할 때 필요한 각종 동기화 문제 없이 마치 싱글 스레드 코드를 짜는 것과 거의 동일한 방식으로 코드를 작성할 수 있으면서도 그러한 코드들이 "동시에" 동작하는 것처럼 실행해주므로 프로그래머 입장에서 매우 편하다. 실제로는 각 이벤트에 필요한 처리를 하고 다음 이벤트가 발생하기 전까지 비는 시간에 다른 이벤트를 처리하는 코드를 실행시켜주는 방식으로, 시분할과 비슷하지만 문맥 전환이 프로그래머가 작성한 코드에서 명시적으로 다음 이벤트를 기다려야 할 필요가 있을 때 협력적으로 발생한다는 차이점이 있다.

CC++ 같은 언어에서 이러한 코루틴 지원이 잘 안 되는 이유는, 언어적 차원에서 함수 중간에 실행을 멈추고 다른 함수를 실행할 수 있게 해줘야 하는데 스레드 별로 stack이 1개밖에 없는 구조에서는 구현이 어렵고 하나의 함수로 짜야 할 내용을 여러 개의 callback 함수로 쪼개면 코드가 지저분해진다는 단점이 크기 때문이다. 이런 callback형태를 사용하는 게 node.js 개발 환경이다. 현재로써는 이런 콜백 방식이 유연하면서 퍼포먼스가 좋은 방식이지만 언어적으로 약간 더럽다(...). 위에서 기술한 Stackless Python에서 코루틴을 먼저 지원할 수 있었던 것도 이런 배경이 있다.

다행히 Python은 (stackless가 아니더라도) yield 키워드를 통해 함수 실행 흐름을 제어할 수 있기 때문에, 드디어 Python 3.4 버전부터는 표준라이브러리의 각종 파일 입출력, subprocess, socket 통신 등의 기능들을 모두 코루틴화 해주는 asyncio 패키지가 기본 탑재되었다. Python 3.5 버전에는 C에서와 동일한 의미를 가지는 async 함수 선언자와 await 키워드가 포함되어 asyncio 라이브러리에 의존할 수밖에 없던 코루틴 기능을 다른 써드 파티 라이브러리도 보다 쉽게 지원할 수 있도록 바뀌고 코루틴 내부에서의 예외처리 과정이 개선되었다.

5.1. 멀티코어 프로그래밍 하기[편집]

유닉스, 리눅스, macOS의 파이썬에서 멀티코어를 쓰려면 아래와 비슷한 방식으로 소스 코드를 적으면 된다.

import multiprocessing as mp

def work(job_list):
    return job_list + 1

p = mp.Pool(4)
p.map_async(work, job_list).get()


윈도우즈포크(fork) 함수가 없어 아래 코드를 추가해야 한다.

if __name__ == '__main__':
    mp.freeze_support()


[python] 파이썬으로 시도해보는 멀티 코어 프로세싱, 자고 있는 코어들을 깨우기 2015. 11. 24.

6. GUI 프로그래밍[편집]

파이썬에서 GUI 프로그래밍에 가장 많이 쓰이는 것은 파이썬에 기본으로 포함된 Tkinter이지만 그 외에도 wxPython, PyQt, PySide, PyGTK도 쓰인다.

6.1. Tkinter[편집]

Tkinter는 Tk interface의 약자이다. Tk는 GUI 프로그래밍을 위한 라이브러리이다. Tcl은 프로그래밍 언어로 Tk와 함께 GUI에 쓰인다.

7. 라이브러리[편집]

  • 뷰티풀 수프(Beautiful Soup): XML, HTML와 같은 구문 트리 또는 구조화된 데이터 처리를 위한 라이브러리이다.

  • 필로우(Pillow): PIL은 개발이 예전에 중지되었고, PIL의 포크(fork)인 Pillow가 그 역할을 대신하고 있다. Pillow를 쓰자. PIL은 Python Imaging Library의 머릿글자로 간편한 이미지 처리를 위한 라이브러리이다.

  • 스크래피(Scrapy): 스크린 스크래핑 및 웹 크롤링

  • tossi: 야생의 땅: 듀랑고를 개발한 왓 스튜디오에서 개발한 한국어 조사 처리 라이브러리. 같은 인물이 만든 korean 모듈을 대체했다.

7.1. 수학, 통계학, 과학, 공학, 빅 데이터[편집]

수학, 통계학, 과학, 공학, 빅 데이터 프로세싱 관련 라이브러리들

  • 팬더즈(pandas): 데이터 처리와 분석을 위한 라이브러리이다. 테이블 형태의 데이터를 다루기 위한 데이터프레임(DataFrame) 자료형을 제공한다. R의 data.frame을 본떠서 설계한 DataFrame이라는 데이터 구조를 기반으로 만들어졌다. Visualizing Pandas' Pivoting and Reshaping Functions 참조.

  • 싸이파이(SciPy): 고성능 선형대수, 함수 최적화, 신호 처리, 특수한 수학 함수와 통계 분포 등 과학 계산용 함수를 모아놓은 파이썬 패키지이다. 고급 수학 함수, 수치적 미적분, 미분 방정식 계산, 최적화, 신호 처리 등을 위한 다양한 과학 기술 계산 기능이 제공된다.

  • 맷플랏립(matplotlib): 과학 계산용 그래프 라이브러리. Tkinter, wxPython, Qt, GTK+ 등의 그래픽 엔진을 사용할 수 있으며 그래프와 챠트 등을 그리기 위한 시각화 기능을 제공한다. pylab이라는 서브패키지를 제공하여 MATLAB의 그래프 기능을 거의 동일하게 사용할 수 있다.

  • 넘파이(NumPy): 통계, 선형 대수, 행렬 계산, 금융 운용 등을 포함한 과학 계산과 수학 작업. 수치 해석, 특히 선형 대수(linear algebra) 계산 기능을 제공하며 자료형이 고정된 다차원 배열 클래스(n-dimensional array)와 벡터화 연산(vectorized operation)을 지원한다.

  • 심파이(SymPy): 인수 분해, 미분, 적분 등 심볼릭 연산 기능을 제공한다.

  • 씨본(Seaborn): matplotlib에서 지원하지 않는 고급 통계 차트를 그리기 위한 통계용 시각화 기능을 제공하는 시각화 라이브러리이다.

  • 보케(Bokeh): 주피터 노트북이나 웹상에서 자바스크립트로 그래프나 차트를 그려주는 기능을 제공해준다.

  • Pygal: 시각화 라이브러리이다.

  • StatsModels: 통계회귀 분석, 시계열 분석을 위한 라이브러리이다.

7.2. 머신 러닝[편집]

  • 텐서플로우(TensorFlow): 구글에서 오픈 소스로 공개한 기계 학습 라이브러리이다.

  • 케라스(Keras): TensorFlow, Theano, CNTK 등 딥 러닝 라이브러리를 포함하고 있어 쉽게 다층 퍼셉트론 신경망 모델, 컨볼루션 신경 망 모델, 순환 신경망 모델, 조합 모델 등을 구성할 수 있다.

  • 사이킷런(scikit-learn): 파이썬의 머신 러닝 라이브러리이다.

8. 프레임워크[편집]

8.1. 웹 프레임워크[편집]

8.2. 파이게임[편집]

  • Pygame - 파이썬으로 비디오 게임을 제작하기 위한 프레임워크이다.

9. 관련 팁[편집]

  • 계산기가 필요할 때, 명령 프롬프트 또는 터미널을 열고 'python'을 입력하자. 실행창(윈도키 + R)에서 바로 python 쳐도 된다.

  • 문자열을 합칠 때 join을 쓰자. range 함수와 str 함수를 같이 쓰면 매우 편해지는 경우가 있다.

''.join(str(x) for x in range(10))

  • 슬라이스(slice) 문법은 리스트/문자열의 부분을 잘라내는 것 이외에도 다양한 활용이 가능하다.

# 문자열 뒤집기
a = 'abc'
print(a[::-1]) # 출력: cba

# 리스트 복사
a = [1, 2, 3]
b = a[:]
print(b)      # 출력: [1, 2, 3]
print(a is b) # 출력: False

c = [[1, 2], [3, 4]]
d = c[:]
c[0] = [5, 6] # 리스트 자체는 복사되지만
c[1][0] = 7   # 리스트의 원소들까지 복사되지는 않으므로 주의해서 사용하자.
print(c)      # 출력: [[5, 6], [7, 4]]
print(d)      # 출력: [[1, 2], [7, 4]]
print('%s, %s, %s' % (c is d, c[0] is d[0], c[1] is d[1])) # 출력: False, False, True

  • 숫자, 문자, 튜플은 변경 불가능(immutable)하며, 리스트, 집합, 딕셔너리는 변경 가능(mutable)하다. 이때 변경 가능한 자료형은 다른 변수에 대입하여도 그 내용이 공유된다. 그 예로, 아래와 같은 코드가 있다고 하자.

a = (1, 2, 3)
b = a
b += (2, 1)
print(a) # 출력: (1, 2, 3)
print(b) # 출력: (1, 2, 3, 2, 1)

우리가 예상한 대로, 튜플 b만 변경되고, a는 변경되지 않는다. 위의 코드에서 튜플(immutable)을 리스트(mutable)로 바꾸어 보자.
a = [1, 2, 3]
b = a
b += [2, 1]
print(a) # 출력: [1, 2, 3, 2, 1]
print(b) # 출력: [1, 2, 3, 2, 1]

출력을 보면 b만 변경했음에도 a가 변한다는 사실을 알 수 있다. 이것은 모든 변경 가능한 자료형에 적용되며, 심지어 리스트 안의 리스트 같은 것들까지도 공유가 된다. 그러니 원본을 변경하면 안 되는 경우에는 list(), set(), dict()나 copy 모듈 등을 이용해서 객체를 복제하고 작업하자. 변경 불가능한 자료형은 원본을 변경할 수 없기 때문에 해당사항이 없다.

  • 괄호 안에 for 과 if, else 를 넣을 시 주의하자.

#1
list(x for x in range(10) if x%2 == 0)
#2
list(x for x in range(10) if x%2 == 0 else 0)
#3
list(x if x%2 == 0 else 0 for x in range(10))

1은 되지만 2는 되지 않으며 3은 된다. if만 넣을 경우 for 뒤에 써야 하며, 조건을 충족하지 않는 원소들은 생략된다(즉, 1의 결과물은 [0, 2, 4, 6, 8]이다). if와 else 모두를 넣는다면 for 앞에 넣어야 하며 조건을 충족하면 맨 앞, 아니라면 else 다음이 반환된다.

  • 마지막으로 호출된 값(대입이 이루어지지 않은 경우)은 _ 변수에 저장된다. 또한 이 변수에 대입한 값은 버려진다.

  • 멀티프로세싱은 __main__ 블럭 안에 들어가야 한다. 네임스페이스 문제 때문. 들어가지 않으면 오류를 뿜는다.

#if 대신 while도 가능.
if __name__ == '__main__':

  • 파이썬 2와 3에서의 range는 리턴 형식이 다르다. 2에서는 리스트를 리턴하지만 3에서는 range 객체를 리턴한다. 따라서 3에서 range를 리스트로 바꾸려면 아래와 같은 방법들로 전환해야 한다. 파이썬 2에 익숙한 사람은, 파이썬 3의 range는 파이썬 2의 xrange와 동일한 역할을 한다고 생각하면 된다.

list(range(10))
[*range(10)]

9.1. 개발 환경[편집]

기본적으로 제공되는 파이썬 IDLE이 있지만, 아무래도 기능이 부족하기에 별도로 출시된 IDE텍스트 에디터를 사용하는 경우가 많다. 대표적으로는 JetBrains 사의 PyCharm이 있고[18], 그 외에도 Sublime Text, Atom, Notepad++ 등이 사용된다. 또한 비주얼 스튜디오 코드에도 파이썬 플러그인이 있으며, 이클립스에는 PyDev라는 이름의 플러그인이 있다.

안드로이드 상에서는 QPython이라는 IDE를 돌리거나 Kivy라는 멀티터치 프레임워크를 사용하여 개발할 수 있다.

10. 여담[편집]

  • 구글에서 python이라고 검색하면 제일 위에 뜨는 게 바다 괴물이나 이 아니라 이거다.

  • Python의 창시자 귀도 판 로썸은 구글에 입사했다가 2012년 12월 7일부로 드롭박스에 입사했다.

  • 문명 4의 스크립트 언어로 쓰였다. Lua와 더불어 게임 스크립트 언어의 양대 산맥.

  • 심즈 4 역시 Python을 기반으로 해서 동작한다. 클라이언트를 살짝 보면 수많은 .pyo 파일들의 향연을 볼 수 있다. 심즈 4의 최적화는 나름 우수한 편. 근데 pyo가 3.5 버전에서 삭제되고 pyc로 대체되었다.

  • 킹덤 언더 파이어의 엔진에도 쓰였다. 500여 개의 자체모듈이 누더기처럼 돌아갔다고 한다.

  • 월드 오브 탱크는 상당 부분이 파이썬으로 구현되어있다. 유저가 작성하는 모드도 로직 부분은 파이썬으로 구현된다.

  • EVE 온라인은 Python의 경량/고속 실행 버전인 Stackless Python으로 작성되었다. 개발사 CCP Games는 파이썬 재단의 정식 후원자이기도 하다. 2000년대 초에 싱글코어 CPU가 계속 쓰일 줄 알고 서버 코드를 구버전 파이썬으로 짰다가 다중 코어 사용이 힘들어지자[19] 눈물겨운 마개조를 거듭하여 파이썬이라는 언어가 제공할 수 있는 처리 능력을 한계치까지 뽑아서 쓰고 있다.

  • 여기 번역판에서 인터프리터 설치 없이 웹 상으로 배워볼 수 있다. 단, 한글 번역판에서만 있는 오류도 있으니 주의.

  • NumPy+SciPy+matplotlib 조합이 과학 공학 계산용으로 써볼만 하다는 의견도 있다.

  • 파일:external/regmedia.co.uk/swift_benchmark.jpg
    2014년 6월 WWDC에서 애플이 공개한 Swift라는 언어에게 220배 느리다고 까였다. 유저들은 C 바인딩인 ctypes를 출동 시킨다고 부들부들... 하지만 JIT 없는 동적 인터프리터 언어와 컴파일 언어의 성능을 비교하면 어떤 언어를 비교하더라도 당연히 후자가 압도적으로 유리하다는 점에서 이건 비교 자체가 잘못된 것이다. 게다가 암호화 같은 CPU heavy한 작업은 보통 다 C로 짜서 붙인다. Python 해쉬 라이브러리인 hashlib만 해도 코어가 전부 C로 되어있다.

  • 객체 지향 프로그래밍을 배울 때 추천할 만한 언어이다. 많은 대학들이 C++ 환경에서 가르치지만, 이 경우 필요한 객체를 만들어서 쓰는 실습이 많은데 대부분 이미 존재하는 객체를 가져다 쓴다는 개념을 이해하지 못하는 경우가 많다. STL을 쓰면 달라지지만 실습에서 STL을 요구하는 문제가 나오는 경우도 드물고, 주로 사용되는 문자열 변환, 배열 관련 연산 등은 파이썬에서 따로 임포트할 필요 없이 자료형 자체가 이미 클래스로서 편리하게 클래스 함수를 던져주기 때문에, 클래스의 재활용이라는 측면을 훨씬 이해하기 쉽다. 무엇보다 하루면 다 배울 수 있는 언어이기도 하고. 다만 대학들도 아무런 이유 없이 C++을 객체 지향 입문용으로 채택한 건 아니다. 많은 학생들이 프로그래밍 언어 중 C를 가장 먼저 배우기에, C++은 그나마 익숙한 개념들을 이용해서 객체 지향을 학습할 수 있게 한다. 물론 C++ 프로그래밍은 C 프로그래밍과는 패러다임 자체가 다르므로 주의가 필요하지만, 적어도 "C언어의 구조체 안에 함수를 정의할 수 있게 하면 C++이다"는 식의 낚시로 학생들에게 심리적 편안함을 줄 수는 있다. 최근에는 객체 지향 입문용 언어로 C++보다 파이썬을 먼저 가르치는 대학도 늘어나고 있는 추세라, 파이썬부터 먼저 공부하는 것도 나쁘지 않다.

    • 파이썬 인터프리터라도 열어서 아무 모듈이나 임포트하거나, print 함수를 dir(print)를 입력해보면 좀 더 잘 알게 된다. 이것에 관해서 모아놓은 책도 있다. 우리가 사용했던 함수가 다르게 보일 것이다. Fluent Python(번역서: 전문가를 위한 파이썬)이라는 책이 있다.

  • 도널드 글로버가 자신의 노래 가사에 Python을 배우라는 가사를 넣기도 했다.

10.1. 파이썬의 철학(The Zen of Python)[편집]

앞서 설명했던 파이선의 철학이 담긴 문장으로 이스터 에그형태로 파이썬에 포함되어 있다. 콘솔에서 "import this" 입력. 원문 링크

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!


아름다운 게 못생긴 것보다 낫다.
명시적인 게(명확한 게) 암시적인 것보다 낫다.
단순한 게 복잡한 것보다 낫다.
복잡한 게 엉클어진 것보다 낫다.
단일한 게 계층적인 것보다 낫다.


전체 해석은 https://zetawiki.com/wiki/젠_오브_파이썬 참조.
dir(this)를 하면 ROT13으로 인코딩된 this.s를 확인할 수 있다. this.d로 dictionary( {} )를 사용해 해독하면 원문이 나온다.

[1] Python의 엄청나게 빠른 개발 속도와 생산성을 두고 개발자들 사이에서 유행처럼 퍼진 말이다.[2] 정확히는 파이썬의 '사실상의 표준' 구현인 CPython이 인터프리터 구조를 따르고 있다. 파이썬 코드를 파이썬 바이트코드(bytecode)라는 것으로 변환(컴파일)하고, 이 바이트코드를 해석(인터프리트)하는 방식으로 되어 있다(JVM과 동일한 방식이다). 어떤 언어가 컴파일되는지 / 인터프리트되는지의 여부는 언어를 어떻게 구현하느냐에 따라 달라진다. 실제로, 파이썬(의 확장) -> C로 변환하는(트랜스컴파일러) Cython, 기본적으로는 인터프리터 방식이지만 필요할 때는 코드를 기계어로 컴파일하는(JIT 컴파일러) PyPy 등의 물건들이 존재한다.[3] PyCharm, VS Code 등의 최신 에디터는 Tab을 눌러도 공백으로 자동 변환되어 입력된다. 따라서 이러한 기능이 지원되는 에디터라면 굳이 스페이스 바를 네번이나 치지 않아도 된다.[4] return 대신 yield를 써서 생성기(generator)를 반환한 경우.[5] 16학번부터 적용. 그 전까지는 첫 프로그래밍 언어로 C를 배웠다.[6] 기존에 MATLAB으로 진행되던 공학컴퓨터프로그래밍 강의가 현재 Python으로 대부분 대체되었다.[7] 비이공계 학생만 해당. 2015년부터 필수교양인 '컴퓨터 프로그래밍'에 포함되어있다.[8] 비이공계 학생들에게 해당, 2016년도 신입생부터 실시하는 컴퓨팅 사고력 필수 교양에서 Python 기초 문법과 응용을 가르치고 있다.[9] 원래 언어 쪽에서 Multilingual과 같은 뜻으로 쓰였으나, 컴퓨터, IT 업계에서는 여러 프로그래밍 언어를 능숙하게 구사하여 적재적소에 잘 조합하여 쓸 수 있는 능력을 뜻한다.[10] 해당 스트링을 셸에서 실행시키는 함수.[11] C 시간에 스택 영역 힙 영역 할 때 나오는 그 스택이다.[12] C 레벨에서 만들어주는 스택이라 "C로 짜여진 프로그램"인 CPython은 손을 댈 수가 없다. 원칙적으로는 말이지 [13] CPython은 GPL 호환의 독자 라이센스를 가진 오픈소스 프로젝트다.[14] 메모리의 용량이 유한한 이상 스택 오버플로우 에러가 안 날 수는 없다.[15] OS가 직접 관리하는 쓰레드가 아닌, 유저 프로세스 차원에서 직접 돌리는 쓰레드. 그린 쓰레드(green thread)라고도 하는데 Ruby 1.8까지 지원하는 쓰레드가 바로 이것이다.[16] 사실 GIL 방식으로 만들 당시 싱글코어가 일반적이었다는 걸 생각해보면 싱글코어에서의 멀티쓰레딩 목적 자체가 멀티코어 성능 향상보다는 이런 다중 이벤트 루프 구현을 하기 위한 것이라고 봐야 하며, 그런 관점에서는 GIL이 합리적인 선택이었다고 할 수 있다.[17] 단, 코루틴이라는 개념 자체가 이런 최근의 프로그래밍 언어에서 처음으로 등장한 것은 아니다. 코루틴의 개념은 1950년대에 이미 나왔다.[18] Django 같은 웹 프레임워크는 유료 버전인 프로페셔널 에디션에서만 지원된다.[19] 전장에서 일어나는 일을 제외한 나머지 시시콜콜한 일을 다른 코어로 돌리기는 하였으나, 게임의 최소 단위인 전장은 구조상의 한계로 하나의 코어만 동원할 수 있다.[20] 강남 코엑스에서 13~14일 아카마이에서 15일(튜토리얼).