파이썬

From Hidden Wiki
Jump to navigation Jump to search

개요

파이썬(Python)은 프로그래밍 언어의 일종이다. 창시자는 귀도 반 로섬(Guido van Rossum)이다. 네덜란드어 발음으로 히도 판 로쉼이다. 1989년 크리스마스 주에 연구실은 닫혀있고 심심해서 만들었다. 귀도가 즐겨 보던 영국의 6인조 개그 그룹 몬티 파이선(Monty Python)에서 이름을 땄다. 귀도 반 로섬구글에 입사했다가 2012년 12월 7일부로 드랖박스(Dropbox)로 이직했다. 한 헤드헌터로부터 경력직 파이썬 개발자 취업 제안을 받은 적도 있다고 한다. 즉, 파이썬 창시자에게 파이썬 '경력직' 개발자를 구하는 수준의 메일을 보낸 것(...). https://plus.google.com/115212051037621986145/posts/R8jEVrobbRj ~~면접관: 파이썬 어느정도 하시나요? 귀도: 제가 만들었는데요.~~


Java, C language, C++, Python, C#이 전세계에서 가장 많이 쓰이는 다섯 개의 프로그래밍 언어이다.

C샾마이크로소프트에서 만들었다. 거의 Apple용으로만 쓰이는 Objective-C처럼 C#도 거의 Microsoft용으로만 쓰인다. 오브젝티브-CC 언어 파생 언어 중 하나이다. C#을 제외한 자바, C 언어, C플플, 파이썬은 리눅스, 안드로이드, 맥OS, 아이OS(iOS), 윈도우즈운영 체제를 가리지 않고 다양한 개발에 쓰인다.

Python은 구글의 3대 개발 언어 중 하나로 알려져 있다. 나머지 2개는 C++Java이다. 하지만 최근에 Go로 넘어가려는 움직임이 보인다 카더라. 구글C 언어와 비슷한 Go 언어(Go language)와 Java와 비슷한 코틀린(Kotlin)을 공식 언어로 지정하여 사용하고 있다. 애플Objective-C에서 스위프트(Swift)라는 Objective-C와 호환되는 새로운 언어로 주력 언어를 변경 중이다.


루비(Ruby)라고 파이썬과 유사한 프로그래밍 언어가 일본에서 만들어졌다. 루비도 세계적으로 꽤 많이 쓰인다.


안드로이드의 경우 플레이 스토어(Play Store)에서 SoloLearn에서 만든 Learn Python같은 (app)을 설치하여 파이썬 프로그래밍을 배워도 좋다. 지금은 여러 잡다한 프로그래밍 학습 앱이 "SoloLearn: Learn to Code for Free" 하나로 합쳐져서 Learn Python 대신에 새로 나온 앱을 깔아야 한다.


프로그래밍을 배우기 전에 찰스 펫졸드코드라는 책을 읽어보기를 추천한다. 영어판은 구글에 charles petzold code pdf라고만 쳐도 pdf 파일이 나오며, 한국어판은 도서관에서 빌리거나 사서 봐야 한다.

  • [Book] CODE 코드

https://blog.outsider.ne.kr/1053

  • 찰스 펫졸드의 코드:CODE

http://freesearch.pe.kr/archives/2406


언어 구현

보통 말하는 Python은 C 언어로 구현되었으며, 다른 구현체와 구분하여 언급할 때에는 CPython이라고 표기한다.

CLR 바이트코드로 구현된, 즉 닷넷 프레임워크 위에서 동작하는 IronPython, CPython에서 C 스택을 없앤 Stackless Python, JVM 바이트코드로 구현되어 JVM 위에서 돌아가는 Jython, 파이썬 자체로 구현된 PyPy 등이 있으며 이 가운데 오리지날은 CPython이다. 이전 버전 문서에는 C#으로 구현된 Ironpython, Java로 구현된 Jython이라고 되어있었으나 이는 명백한 오류다. Jython이 JVM 바이트코드가 아니라 Java로 구현된거라면 안드로이드 Dalvik VM에서는 왜 안돌아간다고 생각하는가?

파이썬 창시자 Guido van Rossum이 다니는 Dropbox에서 파이썬을 프론트엔드로 하고 LLVM을 백엔드로 사용하는 Pyston이란 JIT 기반 파이썬을 개발하였다. https://github.com/dropbox/pyston

LLVM(이전 이름: Low Level Virtual Machine)은 컴파일러의 기반구조이다. 프로그램을 컴파일 타임, 링크 타임, 런타임 상황에서 프로그램의 작성 언어에 상관없이 최적화를 쉽게 구현할 수 있도록 구성되어 있다.

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

PyPy

본격 Python으로 직접 구현되는 Python. 언뜻 보면 CPython보다 느릴 것 같지만 실제로는 더 빠른 실행결과도 보여주는 흠좀무한 녀석이다. 어떠한 외계의 기술이 적용되어서 이것이 가능한지는 파이파이(PyPy) 문서를 참조하라.


2007년에 처음 발표된 Python의 언어 구현 중 하나로, C로 짜인 기존의 CPython과 달리 Python으로 Python을 만드는 프로젝트이다. 부트스트래핑이라고 한다. 여기까지 얘기하면 뭔가 이상한 짓 하는 프로젝트 내지 실험적인 프로젝트처럼 느껴지겠지만, 이 프로젝트의 진짜 놀라운 점은 기존 CPython보다 전혀 느리지 않을 뿐더러, 오히려 성능면에서 CPython을 능가하고 있다는 거다. 나아가 http://speed.pypy.org/ 에서 보이는 대로, 계속해서 빨라지고 있다!

표준 구현인 CPython과의 속도비교. http://speed.pypy.org/ PyPy를 개발하면서 지속적으로 업데이트 하고 있다.


이 구현은 애초에 그저 장난질 하려고 시작한 프로젝트가 아니다. Psyco( http://psyco.sourceforge.net/ )라고 하는, 기존 파이썬 위에다가 JIT(Just-In-Time) 컴파일을 구현해서 실행성능을 높히는 프로젝트가 있었는데, 이걸 개발하던 Armin Rigo( http://codespeak.net/~arigo/ )라는 사람이 아예 JIT 컴파일을 하는 파이썬을 처음부터 다시 구현하기로 생각했다. 그래서 2003년부터 PyPy 개발을 시작하여 유럽연합의 연구자금 지원을 받아가며 지금도 개발하고 있다.

2017년 8월 기준으로, PyPy3는 윈도우 바이너리가 없으므로 리눅스 바이너리를 실행시켜야 한다. 윈도우 10이라면 1주년 업데이트에 포함된 리눅스 배시 기능을 쓰거나, 윈도우로 리눅스 어플리케이션을 돌리는 프로그램을 이용할 수도 있다.

어떻게 구현하나

기계어컴파일하지 않고 기껏해야 인터프리팅 성능을 빠르게 하기 위해 스크립트만을 쓰는 Python을 가지고 파이썬으로 돌리는 파이썬을 어떻게 만들었을까. PyPy의 접근법은 이렇다.

1. 먼저 RPython이라고 하는, 파이썬 문법을 엄격하게 만들어 컴파일이 되게 만든 해석기(translate.py)를 Python 코드로 작성한다. RPython는 Python의 일부만 구현한 언어(부분 언어)이기 때문에 모든 RPython 코드는 Python 코드이기도 하다. (반대는 성립하지 않는다.)

2. RPython의 효과적인 컴파일을 위해 다른 언어로 툴체인을 만든다. 시뮬레이터에뮬레이터를 제작하는 때에도 이 과정을 반드시 거친다.

3. Python 구현(런타임)을 RPython 문법으로 작성한다.

4. 3에서 만든 구현을 1 또는 2에서 만든 RPython 해석기로 컴파일한다.

5. 4으로 만든 후보를 이전 또는 다른 구현과 비교(성능 측정), 만족스럽지 않으면 수정한다.(nightly builds)

6. 5에서 만족스러운 결과를 냈다면 출시하고 1 또는 2부터 다시 시작한다.(release)

~~뭔가 속는 느낌이지만~~ 처음 한번만 기존 파이썬의 도움을 받으면 그 다음부터는 스스로 만든 구현으로 저 과정을 자체적으로 계속 반복할 수 있다. 이게 얼핏 보면 '닭이 먼저냐 달걀이 먼저냐' 같은 것으로 착각할 수도 있지만, 이런 식의 접근법은 실제로 프로그래밍 언어를 제작할 때 해당되는 사항이며, 더 좋은 장비의 개발을 위해 기존의 장비를 사용하는 것과 다름이 없다. 일례로 유명 c/c++언어 컴파일러인 gcc도 c/c++로 작성되었다. 파이썬이 스크립팅 언어이기 때문에 일견 특이해보이는 것일 뿐, 인터프리터는 어짜피 컴파일된 상태로 돌아가므로 같은 원리다. 이러한 이유로 로고가 우로보로스인 셈. 다만 PyPy는 문자 그대로 진화하고 있다.

사실 이런 식으로 어떤 언어로 자기 자신을 구현하는 것을 부트스트래핑(Bootstrapping) 또는 부팅(Booting. 운영체제의 부팅과 같은 어원이다.)이라고 하는데, 사실 이렇게 하는 이유는 처음부터 작업하는 것보다 생산성에서 낫기 때문이다. 처음부터 어셈블리어로 작업하면 이론상 최강의 성능을 발휘할 수는 있으나 그 가능성은 매우 낮고 생산성도 최악이다. 최적화가 그래서 힘들다. 이 때문에 대부분의 프로그래밍 언어도 초창기에는 어셈블리어나 다른 고급 언어의 도움을 받지만, 일정 단계를 넘어서면서 그 한계가 오면 스스로의 컴파일러/인터프리터를 제작하게 된다. Haskell 컴파일러인 GHC와 C/C++ 컴파일러인 GCC가 대표적인 예. 물론 생산성에 중점을 두기 때문에 성능이 눈에 띄게 빨라지는 일은 잘 드러나지 않으며, 단지 우연한 발견 등 여러 이유로 성능이 향상되는 것 뿐이다. PyPy의 경우 Python의 한계를 극복하기 위해 정적인 컴파일이 가능한 RPython을 따로 만들었고 뒤에도 언급할 듯 성능 향상을 위해 7년이라는 긴 세월을 소모했는데, 이것도 어셈블리어로 처음부터 하는 것보다는 짧은 것이다. 컴퓨터 하드웨어의 발전도 마찬가지다. 처음 IC나 LSI를 설계할 때는 레이아웃을 손으로 그렸지만, 지금 나오는 칩들은 손으로 하기에는 회로의 규모가 지나치게 크기 때문에 전부 CAD로 개발하고 있다. 사실 이러한 일은 망치를 만들기 위해 망치를 쓰거나 간석기를 만들기 위해 뗀석기를 썼던 것 처럼 인류의 역사를 대표하는 방법론 중 하나이므로 전혀 속는 느낌 가질 거 없다.


특징

파이썬객체 지향 프로그래밍(object-oriented programming) 언어에 속한다. 객체 지향 프로그래밍 전에 절차적 프로그래밍(procedural programming) 언어가 먼저 개발되었다. 절차적 프로그래밍 언어에서 구조적 프로그래밍이 나왔다. 현재는 절차적 프로그래밍 언어에도 객체 지향 프로그래밍 개념이 포함되어있다.

객체 지향을 배울때 추천할만한 언어이다. 많은 대학들이 C++ 환경에서 가르치지만, 이경우 필요한 객체를 만들어서 쓰는 실습이 많은데 대부분 이미 존재하는 객체를 가져다 쓴다는 개념을 이해하지 못하는 경우가 많다. STL을 쓰면 달라지지만 실습에서 STL을 요구하는 문제가 나오는 경우도 드믈고 주로 사용되는 문자열 변환, 배열 관련 연산 등은 파이썬에서 따로 임포트할 필요없이 자료형 자체가 이미 클래스로서 편리하게 클래스 함수를 던져주기 때문에, 클래스의 재활용이라는 측면을 훨씬 이해하기 쉽다. 무엇보다 하루면 다 배울 수 있는 언어이기도 하고. 예전에는 한국을 포함하여 대부분의 대학들이 C++이나 Java 같은 실제 회사에서 많이 쓰는 언어 위주로 수업을 개설했으나, 미국대학들은 개론 수업 언어를 Python으로 옮겨가는 추세이다. UC 버클리 컴퓨터과학 개론수업인 CS 61A 를 인터넷 강의로 들어보자!

인터프리터 언어

인터프리터(interpreter)는 소스 코드(source code)를 한 줄씩 읽어 내려가며 실행하는 프로그램이다. 컴파일러와는 대조적이며, 이 방식을 쓰는 프로그래밍 언어는 정말 많다. 대표적인 것이 Python이다. 스크립트 언어의 사실상 전부가 해당 언어의 인터프리터를 가지고 있으며, 각종 DSL(도메인 특화 언어)의 해석 엔진도 인터프리터로 구현된다.

인터프리터는 실행 시마다 소스 코드를 한 줄씩 기계어로 번역하는 방식이기 때문에 실행 속도는 정적 컴파일 언어(이하 '컴파일 언어')보다 느리다. 이를 해결하기 위하여 바이트코드 컴파일러를 이용해 소스 코드를 가상머신 타겟의 바이트코드(bytecode)로 변환하거나, 반복적으로 쓰이는 함수와 클래스 등의 기계어 코드를 캐싱하는 JIT 컴파일러를 인터프리터에 내장하는 방식이 도입되었다. 바이트코드로 변환하는 것은 기계어로 변환하는 것에 비하면 비교적 간단하다. 바이트코드(Bytecode)는 고급 언어로 작성된 소스 코드를 가상머신이 이해할 수 있는 중간 코드로 컴파일한 것을 말한다. 가상머신은 이 바이트코드를 각각의 하드웨어 아키텍처에 맞는 기계어로 다시 컴파일한다. 어셈블리어에 가까운 형태를 띄고 있으며 어떨 때는 가상머신용 오브젝트 코드까지 바이트코드라고 부르기도 한다.

여기까지 읽었다면 그 느린 것을 왜 쓰느냐는 의문에 도달하겠지만, 인터프리터 언어는 프로그램 수정이 간단하다는 장점이 있다. 컴파일러는 소스 코드를 번역해서 실행 파일을 만들기 때문에 프로그램에 수정 사항이 발생하면 소스 코드를 다시 컴파일해야 한다. 프로그램이 작고 간단하면 문제가 없지만 프로그램 덩치가 커지면 컴파일이 시간 단위가 되는 일이 많아진다. 하지만 인터프리터는 소스 코드를 수정해서 실행시키면 끝. 이 장점 때문에 인터프리터 언어는 수정이 빈번히 발생하는 용도의 프로그래밍에서 많이 사용된다. 이 장점을 최대한 살려서 인터프리터를 적극적으로 채용한 것이 스크립트 언어다.

또한 프로그래밍 언어 차원에서 동적인 기능을 지원하기 유리하다. 물론 컴파일러도 어느 정도의 동적인 기능은 지원 가능하지만, 실행 시간에만 어떤 모듈을 사용할지 결정하는 것이나 사용자가 입력한 임의의 프로그램을 평가하는 것이라던가 심지어 이미 실행되고 있는 코드 자체를 수정하며 실행하는 등의 기능을 컴파일러로는 구현할 수가 없다. (만약 컴파일된 프로그램인데 이러한 기능을 전부 사용할 수 있다면 인터프리터가 해당 프로그램에 내장되어 있을 것이다.)

디버그를 하는 방식이 컴파일러로 컴파일하여 실행하는 경우와 다른 편이다. 컴파일러와 달리 인터프리터의 경우 코드를 한줄씩 실행시킬 수도 있기에 어떤 코드를 작성하고 바로 실행해보고 문제가 있으면 바로바로 수정하는 방식이 가능하다. 구문 오류의 경우 예전 인터프리터의 경우에는 정말로 한줄씩 읽어서 실행했기에 구문 오류가 나오는 부분 전까지는 멀쩡하게 실행되는 경우가 많았다. 그러다보니 실행되지 않는 부분에는 오류가 있어도 오류로 처리되지 않는 경우도 존재하였다. 하지만 최근에는 성능 등의 이유로 파일을 실행하면 파일 전체를 컴파일 하는 방식을 사용하기 때문에 처음부터 구문 오류를 전부 잡아주는 인터프리터도 많아지고 있다.

소스 코드가 쉽게 공개된다는 단점이 있다. 컴파일되는 언어도 기계어를 읽으면 프로그램이 어떻게 동작하는지 알 수 있으며, 디컴파일러를 이용하여 원본 언어로 변환하는 것도 불가능은 아니다. 하지만 인터프리터를 주로 사용하는 언어의 경우 바이트코드 등으로 컴파일해서 배포하는 경우도 잘 없을 뿐더러, 지원한다고 해도 컴파일 전/후 언어가 비교적 단순한 편이라서 쉽게 디컴파일이 가능하다. 암호화를 해도 어차피 실행될 때는 복호화되니 무용지물. 그나마 식별자들을 전부 이상하게 바꾸고 해석하기 힘들게 난독화하는 정도 외에 할 수 있는 방법이 없다.

JIT 컴파일

JIT 컴파일(just-in-time compilation) 또는 동적 번역(dynamic translation)은 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법이다. 이 기법은 프로그램의 실행 속도를 빠르게 하기 위해 사용된다.

전통적인 입장에서 컴퓨터 프로그램을 만드는 방법은 두가지가 있는데, 인터프리트 방식과 정적 컴파일 방식으로 나눌 수 있다. 이 중 인터프리트 방식은 실행 중 프로그래밍 언어를 읽어가면서 해당 기능에 대응하는 기계어 코드를 실행하며, 반면 정적 컴파일은 실행하기 전에 프로그램 코드를 기계어로 번역한다.

JIT 컴파일러는 두 가지의 방식을 혼합한 방식으로 생각할 수 있는데, 실행 시점에서 인터프리트 방식으로 기계어 코드를 생성하면서 그 코드를 캐싱하여, 같은 함수가 여러 번 불릴 때 매번 기계어 코드를 생성하는 것을 방지한다.

최근의 자바 가상 머신과 .NET, V8(node.js)에서는 JIT 컴파일을 지원한다. 즉, 자바 컴파일러가 자바 프로그램 코드바이트코드로 변환한 다음, 실제 바이트코드를 실행하는 시점에서 자바 가상 머신이 바이트코드를 JIT 컴파일을 통해 기계어로 변환한다.

CPythonJIT를 지원하지 않으며 PyPyPyston은 JIT를 기본으로 지원한다. JythonIronPython은 그들이 빌드(build)하는 가상 머신의 JIT 컴파일러를 사용한다. Cpython의 경우 과학이나 천체물리학에 쓰는 NumbaHOPE 모듈을 사용하여 JIT 컴파일러를 쓸 수 있다. https://numba.pydata.org/ https://github.com/jakeret/hope

동적 타입 언어

정적 타입 언어: 자료형(Type)이 고정돼 있는 언어. 설명이 어려운데 간단히 얘기하자면 정수형으로 정의한 1은 계속 정수형 1로 남아있다. 이걸 실수형 1.0으로 바꾸려면 명시적인 형변환(Type casting)을 해줘야 한다. 묵시적 형변환이 이루어지는 경우도 있지만 제한적이다.

동적 타입 언어: 자료형이 그것을 처리할 함수(또는 메서드)에 따라 그때그때 바뀌는 언어. 예를 들어 정수형 1을 정의했어도 그걸 처리할 함수가 문자열을 받아들이게 설계돼있다면 자동으로 정수형 1을 문자 1로 바꿔준다.


정적 타입 언어가 별 거 아닌 것처럼 느껴질 수도 있지만 실은 프로그래머들을 짜증나게 하는 주범이 바로 형변환(Type casting)이기 때문에 동적 타입 언어는 이런 점에서 매우 강점을 가진다. 특히 객체 지향 언어에서는 동적 타입 및 그것의 일반화버전이라 할 수 있는 덕 타이핑(Duck typing)이 프로그래머에게 수많은 혜택을 준다. 예를 들어 오리라는 타입과 닭이라는 타입이 있고 둘 다 날아오르는 기능이 있다면 정적 타입 언어에서는 상위 인터페이스를 추출하는 등의 부가 작업이 쩌는데 덕 타이핑을 지원하는 언어에서는 그냥 넣어버리면 알아서 난다. 물론 단점도 있는데 고래 같이 못 나는 타입을 집어넣으면 실행시간 오류(런타임 에러)를 뱉어버린다는거. 정적 타입 언어는 이런 문제가 없다...고 알려져있지만 거짓말이고 정적 타입 언어도 닭은 닭인데 통닭 같이 못 나는 타입을 집어넣는 바람에(기술적으로는 해당 메서드가 구현이 안된 객체) 런타임 에러가 나올 수 있다.

그런데 하스켈(Haskell)은 정적 타입 언어다. 그런데도 하스켈 코드에는 형 변환 연산자가 없다. 이게 어찌된 일이냐 하면 하스켈 언어는 정적 타입 언어이지만 강력한 타입 추론 기능을 내장하고 있어 형변환을 언어 차원에서 자동으로 해 준다. 동적 타입 언어 역시 자동 형변환을 제공하는데 무슨 차이가 있냐면 그 형변환을 런타임에 하느냐 컴파일 타임에 하느냐의 차이다. 즉 버그가 발생하는 시점을 런타임에서 컴파일 타임으로 끌어당긴다. 타입 추론 엔진은 딱히 하스켈 같은 선언형, 함수형 언어에만 도입할 수 있는 건 아니므로 신형 설계가 적용된 언어라면 명령형, 객체 지향 언어라도 타입 추론을 할 수 있다. 단지 정적 타입 언어로 유명한 C나 자바에 타입 추론 엔진이 없을 뿐이지. 여기서 타입 추론은 묵시적 형변환과 동의어가 아니다. 겉으로 보이는 건 묵시적 형변환하고 똑같지만.

파이썬이 동적 타입 언어(dynamically typed language)라는 점이 큰 프로젝트에서는 단점으로 작용하여 자료구조 설계나 디버깅이 어렵다는 지적도 있다. 다만 "정적 타입 언어 vs. 동적 타입 언어" 논쟁은 서로의 장단점이 있으며 일종의 종교논쟁 취급 받는다. 일례로 OCaml같은 강력한 타입 인터페이스(Hindly-Milner)를 가진 경우라 할지라도 타입 에러 정도는 거의 모두 컴파일 타임에 잡아내는 있는 반면에, 모든 버그가 타입 에러는 아니기 때문에 여전히 테스트 및 디버깅 과정은 필요하며, 타입 시스템으로 인한 부담 때문에 빠른 구현에는 부담이 갈 수 있다. 반면에 동적 언어는 빠른 구현의 이점이 있지만 타입 에러가 많이 나는 특징이 있다. 그러나 커버리지가 높은 테스트 세트로 어느정도 커버할 수 있으며 최근의 추세와 부합하는 방식이기도 하다.

높은 생산성

http://xkcd.com/353/ 파이썬의 높은 생산성에 대한 만화 ~~뭐야 이거 2.x 버전이잖아~~

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

참고로 저 xkcd 만화는 파이썬에서 import antigravity라고 하면 나오는 이스터 에그이다.(...) http://www.youtube.com/watch?v=_V0V6Rk6Fp4

디자인 철학

(Perl)의 프로그래밍 모토(motto)는 "프로그래밍하는 데는 한 가지 이상의 방법이 있다.(There's more than one way to do it이고 TMTOWTDI 또는 TIMTOWTDI로 줄여서 얘기함. Tim Toady라고 발음함.)"이다. 반면, 파이썬(Python)의 20번째 PEP(Python enhancement proposal, 파이썬 향상 제안)는 파이썬의 (zen, 선종 불교(교지)을 얘기함.)인 The Zen of Python인데, 파이썬의 젠 중 하나는 "문제를 해결하는 데는 명백한 하나의 방법(그리고 선호되는 오로지 하나의 방법)만 있어야 한다. There should be one-- and preferably only one --obvious way to do it.이다. 이 젠을 펄의 모토와 대비시켜서 간략화한 것이 "문제를 해결하는 데는 오직 하나의 방법만 있다.(There's only one way to do it, 줄여서 TOOWTDI)"이다. PEP 20의 저자는 Tim Peters이다.

Perl의 '하나 이상의 해결법이 존재한다' 와는 정반대로 '가장 아름다운 하나의 답이 존재한다'라는 명제를 모토로 하고 있다. 이 모토 하에 다음과 같은 철학(zen)을 지니게 되었다.

* 아름다운 것이 추한 것보다 낫다.(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)이라는 독특한 개념을 낳게 되었는데, 복잡하지 않으면서 의미가 명확하고, 심플한, 파이썬의 철학을 따르는 것들을 지칭하는 개념이다.

이런 철학 때문에 문법이 굉장히 엄격한 편이다. 예를 들자면, 다른 언어에서는 해도 되고 안 해도 되는 들여쓰기가 이 언어에서는 의무로 들여쓰기 자체로 하나의 코드 블럭이 된다. 코드 블럭을 명시적으로 표시하지 않아도 돼서 비쥬얼 적으로는 굉장히 깔끔한 반면, 자유도를 제약한다는 평도 있다. 특히 C 언어 코드를 종이에 출력해보면 중괄호 있고 없고의 가독성 차이가 의외로 크다.

Python 3

파이썬 2.5 이하 버전에서는 문법이 좀 다르다.

print "Hello, world!"

와 같이 입력해야 한다. 파이썬 3 이상에서는 print가 함수가 되어

print("Hello, world!")

와 같은 문법을 쓴다. https://docs.python.org/2/whatsnew/2.6.html#pep-3105-print-as-a-function 버전 2.6 ~ 2.7에선 둘 다 사용 가능하다.


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

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


Python 3.x 부터는 C++, Java, 액션스크립트 등처럼 내부적으로 모든 문자열을 유니코드로 처리한다. 덕분에 한글 비주얼 프로그래밍 툴 중 하나인 창조처럼 변수나 함수 이름을 한글로 정할 수도 있게 되었다.

이름 = "홍길동"
나이 = 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 버전 이후부터는 문자열 객체에서 가장 많은 공간(바이트)을 차지하는 문자를 기준으로 각 문자가 차지할 공간을 정하도록 변경되었다. https://www.python.org/dev/peps/pep-0393/ 따라서 문자열에 아스키 문자만 포함된다면 각 문자가 1바이트씩만 차지하므로 더 이상 이런 문제가 생기지 않는다. 이런 경우는 심지어 유니코드임에도 Python 2.x의 유니코드 문자열보다 적은 메모리 공간을 차지할 수도 있다! 또한 UCS-4를 모두 지원하는 "wide" 빌드와 UCS-2만 지원하는 "narrow" 빌드의 구분도 사라졌다. 하지만 크기가 변경될 때 그 만큼 속도가 느려지니 장단점이 있다.

C/C++와의 결합

파이썬은 접착(glue) 언어라고도 부르는데, 그 이유는 다른 언어들과 잘 어울려 다른 언어와 결합해서 사용할 수 있기 때문이다. C나 C++로 만든 프로그램을 파이썬에서 사용할 수 있으며, 파이썬으로 만든 프로그램 역시 C나 C++에서 사용할 수 있다.

Python만 쓰는 것이 답은 아니다. 동적 인터프리팅 언어의 한계로 당연히 C, C++ 같은 low-level 언어의 계산속도를 따라갈 순 없으며, 사실 자바스크립트LISP계열 언어 등 동적 언어들을 전체를 주욱 놓고 비교 해봐도 속도가 빠른 편은 아니다. 보통 인터프리터 언어의 속도 문제를 극복하기 위해서 인터프리터에 JIT 컴파일러를 넣는 추세지만 python의 표준인 CPython에서는 구현이 안되어 있다.

C 바인딩인 ctypes도 있다.

사용 용도

기계 학습에 관심을 갖는 사람이 지난 1년간 폭발적으로 증가했다. 역사적인 알파고와 이세돌의 경기가 3월에 있었고, 그 이후로 더욱 주목을 받고 있다. 숫자나 문자 데이터만을 사용하던 기계 학습 방식은 사용자들의 모바일 장비 사용 패턴을 학습하는 것으로 진화하고 있다. 이 점으로만 봐도 기계 학습은 2017년에 더 중요한 자리를 차지할 것이다.

인공 지능은 2016년의 화두였다. 음성 인식과 이미지 분류는 사용자가 접할 수 있는 극히 일부의 기술이며, 기계는 사람과 비슷한 인지 능력을 갖는 정도까지 진화했다. 인공지능과 기계 학습을 이용한 스타트업도 많이 등장하고 있다. 여기에 Google의 텐서플로우(TensorFlow)나 Microsoft의 Cognitive Toolkit과 같은 오픈 소스 프로젝트들도 발표됐다. 기계 학습은 수학과 밀접하게 연관된 분야이며, 기계학습을 시작하기에 도움이 되는 온라인 코스도 나와있다.

가상 현실(Virtual Reality, VR)과 증강 현실(Augmented Reality, AR)이 등장한 지는 좀 되었지만, 비로소 이 기술들은 흥미로운 경험을 제공할 정도까지 성숙했다. Facebook(Oculus Rift), Google(Daydream), Microsoft(Windows Holographic) 들은 가상 현실 플랫폼을 제공하고 서드 파티의 개발자들을 기다리고 있다. VR 헤드셋은 멀미를 줄이거나, 게임 이외의 분야에서도 즐거운 경험을 제공하기 위한 도전을 하고 있으며, 아직은 그 정도 단계이다.

파이썬(Python)을 배우면 오픈 소스토어챝(TorChat)의 소스 코드를 수정하여 자신이 원하는 기능을 마음대로 추가할 수 있다.

파이썬으로 무엇을 할 수 있을까? https://wikidocs.net/7

웹 프로그래밍

일반적으로 익스플로러나 크롬, 파이어폭스와 같은 브라우저를 이용해 인터넷을 사용하는데, 누구나 한 번쯤 웹 서핑을 하면서 게시판이나 방명록에 글을 남겨 본 적이 있을 것이다. 그러한 게시판이나 방명록을 바로 웹 프로그램이라고 한다. 파이썬은 웹 프로그램을 만들기에 매우 적합한 도구이며 실제로 파이썬으로 제작된 웹사이트는 셀 수 없을 정도로 많다.

데이터베이스 프로그래밍

파이썬은 사이베이스(Sybase), 인포믹스(Infomix), 오라클(Oracle), 마이에스큐엘(MySQL), 포스트그레스큐엘(PostgreSQL) 등의 데이터베이스에 접근할 수 있게 해주는 도구들을 제공한다.

또한 이런 굵직한 데이터베이스를 직접 이용하는 것 외에도 파이썬에는 재미있는 모듈이 하나 더 있다. 바로 피클(pickle)이라는 모듈이다. 피클은 파이썬에서 사용되는 자료들을 변형없이 그대로 파일에 저장하고 불러오는 일들을 맡아 한다. 이 책에서는 외장 함수에서 피클을 어떻게 사용하고 활용하는지에 대해서 알아본다.

과학 및 공학 분야

빠른 아이디어 구현이 생명인 연구계에서는 각광 받고 있다(특히 컴퓨터 과학). 연구계에서는 Java를 제외하면 컴퓨터 공학과 외에는 그나마 유일한 경쟁자가 MatLab이라 볼 수 있는데, 오픈 소스가 아니라는 점이 최근 추세와 맞지 않아 입지가 좁아지고 있다. 게다가 패키지 설치를 참 더럽게 이상하게 만들어놨다. Python의 경우는 지원 라이브러리의 대부분이 오픈 소스이기 때문에 저장소에서 그냥 커맨드 라인(pip install) 한줄로 필요한 거의 모든 라이브러리를 가져다 쓸 수 있다.

수치 연산 프로그래밍

사실 파이썬은 수치 연산 프로그래밍에 적합한 언어는 아니다. 수치가 복잡하고 연산이 많다면 C같은 언어로 하는 것이 더 빠르기 때문이다. 하지만 파이썬에는 Numeric Python이라는 수치 연산 모듈이 제공된다. 이 모듈은 C로 작성되었기 때문에 파이썬에서도 수치 연산을 빠르게 할 수 있다.

"NumPy + SciPy + matplotlib" 조합이 과학 공학 계산용으로 써볼만하다는 의견도 있다. ~~조금있으면 독점할 기세이다.~~ http://www.numpy.org/ http://www.scipy.org/ http://matplotlib.org/

데이터 분석

파이썬으로 만들어진 팬더스(Pandas)라는 모듈을 이용하면 데이터 분석을 더 쉽고 효과적으로 할 수 있다. 데이터 분석을 할 때 아직까지는 데이터 분석에 특화된 "(R)"이라는 언어를 많이 사용하고 있지만, 팬더스가 등장한 이후로 파이썬을 이용하는 경우가 점점 증가하고 있다.

(R)과 같이 특정분야에 특화된 언어와 비교하면 꼭 파이썬 라이브러리가 더 다양하다고 볼 수도 없다.

사물 인터넷

사물 인터넷 분야에서도 파이썬은 활용도가 높다. 한 예로 라즈베리 파이(Raspberry Pi)는 리눅스 기반의 아주 작은 컴퓨터이다. 라즈베리파이를 이용하면 홈시어터나 아주 작은 게임기 등 여러 가지 재미있는 것들을 만들 수 있는데 파이썬은 이 라즈베리파이를 제어하는 도구로 사용된다. 예를 들어 라즈베리 파이에 연결된 모터를 작동시키거나 램프에 불이 들어오게 하는 일들을 파이썬으로 할 수 있다.

게임 개발

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

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

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

EVE 온라인은 Python의 경량/고속 실행 버전인 Stackless Python으로 작성되었다. 개발사 CCP Games는 파이썬 재단의 정식 후원자이기도 하다. 2000년대 초에 싱글코어 CPU가 계속 쓰일 줄 알고 서버 코드를 구버전 파이썬으로 짰다가 다중 코어 사용이 힘들어지자, 눈물겨운 마개조를 거듭하여 파이썬이라는 언어가 제공할 수 있는 처리 능력을 한계치까지 뽑아서 쓰고 있다. 전장에서 일어나는 일을 제외한 나머지 시시콜콜한 일을 다른 코어로 돌리기는 하였으나, 게임의 최소 단위인 전장은 구조상의 한계로 하나의 코어만 동원할 수 있다. ~~버그 잡고 최적화하는 프로그래머가 게임 내에서 유명인사가 된 것은 이 게임이 유일하겠지... 이게 다 GIL 때문.~~


소스 코드 작성

지에디트(gedit), 리프패드(Leafpad), xed, 메모장(Notepad) 등 일반적인 문서 편집기로 파이썬 소스 코드를 작성해도 된다. 하지만 이런 일반 문서 편집기보다는, 파이썬 소스 코드 편집기(editor)로 ipython notebook, Sublime Text, Rodeo, PyCharm, Visual Studio Code 등을 많이 사용한다.

리눅스, 맥OS, 윈도우즈에서 모두 사용 가능한 Sublime Text가 괜찮은 것 같다.

들여쓰기

PEP(Python enhancement proposal, 파이썬 향상 제안) 8은 Style Guide for Python Code이며 저자는 Guido van Rossum, Barry Warsaw, Nick Coghlan이다. PEP 8에서는 들여쓰기(indentation)에 (tab)을 쓰지말고, 스페이스 바(space bar)를 쓰라고 하며, "스페이스 바"로 4칸을 띄우라고 규정한다.

들여쓰기(indentation)는 (Tab) 키, 스페이스 바(space bar) 두 번 또는 네 번으로 한다. 운영 체제편집기마다 탭 키의 간격이 다르기 때문에 동일한 스페이스 바를 사용해서 들여쓰기를 하는 게 낫다. 또한 파이썬 코딩 스타일 가이드(PEP 8)에서는 공백 4칸으로 규정하고 있으므로 스페이스 바 네 번으로 들여쓰기를 해주자.

주석

파이썬에서 사람만 알아볼 수 있도록 작성하는 부분을 주석(comment)이라고 합니다. 즉, 주석은 파이썬 인터프리터가 처리하지 않으므로 프로그램의 실행에는 영향을 주지 않습니다. 보통 주석은 코드에 대한 자세한 설명을 작성하거나, 특정 코드를 임시로 사용하지 않도록 만들 때 사용합니다.


주석은 한 줄 주석과 범위 주석 두 가지가 있는데 다음은 한 줄 주석으로 코드에 대한 설명을 작성한 모습입니다.

# Hello, world! 출력


코드 맨 앞에 #을 사용하면 해당 줄은 모두 주석이 됩니다. 따라서 다음 print 함수는 동작하지 않습니다.

#print('Hello, world!')


코드를 뒤에 #으로 주석을 작성할 수도 있습니다. 이때 앞에 있는 코드만 정상적으로 동작하며 # 뒤에 있는 코드는 동작하지 않습니다.

a = 1 + 2 # 더하기
print('Hello, world!') #printf('1234567890')


파이썬에서 여러 줄을 주석 처리할 때는 ' 또는 " 3개를 붙여서 쓰세요.

'''
i am comment!
multiline!!!!
'''


아래는 주석 사용 예시입니다.

#!/usr/bin/python
# -*- coding: cp949 -*-
# 이렇게 앞에 샤프(#) 기호가 있으면 주석문입니다.
print "안녕하세요"    # 각 행 뒤에 주석 기호를 붙일 수도 있음
print 1 + 1           # 출력 결과: 2
"""
여기는 도큐멘트 스트링인데, 블록 코멘트로 사용할 수 있고
이렇게, 큰따옴표 3개 사이에 아무 문장이나 쓸 수 있습니다.
다만, 각 들여쓰기 레벨에 맞아야 합니다.
"""
def example2(x, y):
    z = x + y
    """
    블록 코멘트
    블록 코멘트
    블록 코멘트
    """
    return z
print example2(2, 3)


그리고 소스에서

#!/usr/bin/python
# -*- coding: cp949 -*-

이런 부분은 주석이 아니고 특수한 의미를 가지고 있는 행입니다.

소스 코드 문자 인코딩

파이썬 2까지는 소스 코드의 기본 문자 인코딩(encoding)이 아스키(ASCII)라 # -*- coding: cp949 -*-와 같은 식으로 인코딩을 명시해주지 않으면 한글이 깨졌다. 아스키는 영어 알파벳, 숫자, 키보드에 있는 특수문자만 지원하기 때문이다. 그러나 파이썬 3부터는 기본 인코딩이 유니코드(UTF-8)라 이런 걸 써주지 않아도 한글이 깨지지 않는다.

https://python.flowdas.com/tutorial/interpreter.html#source-code-encoding


대화형 모드

파이썬은 대화형 모드로도 쓸 수 있고, 소스 코드를 만들어서 사용할 수도 있다. 대화형은 한 번에 한 줄씩 입력하면서 바로 바로 실행하는 것이고, 편집기에 소스 코드를 적어 py 파일로 저장하면 한번에 여러 줄의 코드를 순차적으로 실행시키는 것이다.

리눅스라면 기본적으로 파이썬 2.x와 3.x가 기본으로 깔려있다. 맥 OS윈도우즈 사용자의 경우 https://www.python.org/downloads/ 에서 다운로드 받아 설치한다.


칼리 리눅스 기준으로 설명하겠다. 우선 터미널을 띄운다. 그리고 아래와 같이 입력하면 파이썬 2.7.12가 실행된다.

python

그리고 뜬 >>>에 소스 코드를 쓰면 된다.

print("hello world")

라고 치면

hello world

라고 뜬다. print는 모니터 화면에 출력하라는 의미이다. 이제 exit()를 입력하거나 컨트롤 키(Ctrl)와 d 키를 동시에 눌러 빠져나온다.


이제 터미널에

python3

를 입력하여 파이썬 3.5.2를 실행시켜보자. 거기에

print("hello world")

를 입력하면 역시

hello world

라고 뜬다.


요즘에는 파이썬 2.x 버전은 잘 안 쓰니, 파이썬 3.x 버전을 쓰도록 하자. 아래의 모든 예문은 파이썬 3.x를 기준으로 작성되어졌다.


>>> 뒤에 2+4라고 입력하면 6이라고 뜨고, 3+2-7이라고 입력하면 -2이라고 뜬다. 3*7을 하면 21이 뜨고, 3/4를 해보면 0.75가 뜨고, 3/7을 하면 0.42857142857142855가 뜬다. *는 곱하기고, /는 나누기다. 역시 exit()를 입력하여 종료시킨다.


>>> x = 5
>>> if x == 10:
...      print('10입니다.') # ← 들여쓰기 4칸
... else:
...      print('10이 아닙니다.') # ← 들여쓰기 4칸
... # ← 빈 줄에서 엔터 키를 누름
10이 아닙니다.

위와 같이 대화형 모드에서도 if문과 else문도 사용 가능하고, 여러 줄의 코드도 실행할 수 있다.


터미널에서 실행하는 소스 코드

Sublime Text 등 파이썬 소스 코드 편집기를 아무거나 열어서 다음 소스 코드들을 입력한 후 실행시켜 보자.

만약 소스 코드 파일의 이름이 bozy.py인 경우 리눅스터미널에서 bozy.py 파일이 있는 디렉터리로 이동한 후

python3 bozy.py

python bozy.py

라고 입력하면 실행된다. python3라고 입력하면 파이썬 3가 실행되고, python이라고 입력하면 파이썬 2.7 버전이 실행된다. 리눅스 배포판에 따라 파이썬 3가 기본인 경우도 있다. 만약 my sister bozy.py처럼 파일 이름에 띄어쓰기가 들어갈 경우

python3 "my sister bozy.py"

python3 'my sister bozy.py'

처럼 따옴표로 묶어주면 된다.


윈도우즈의 경우 파이썬을 설치할 때 “Add Python 3.6 to PATH”의 체크박스를 체크해줘야 한다. 이 부분은 Python 3.6을 컴퓨터가 현재 cmd.exe의 어느 디렉토리에 있다 하더라도, 파이썬을 실행 시킬 수 있도록 해주는 것입니다. 즉, 컴퓨터 시스템 전반에 걸쳐 쉽게 참조할 수 있도록 만들어 놓은 변수인 환경 변수를 설정하는 것입니다. 이걸 설정해야 python이라는 명령어만으로 파이썬을 실행할 수 있다. "시작 → 모든 프로그램 → 보조 프로그램 → 명령 프롬프트" 또는 "시작 → 실행 → cmd"를 하고 bozy.py 파일이 있는 폴더로 이동한 후

python bozy.py

라고 입력하면 된다. 설치할 때 “Add Python 3.6 to PATH”를 체크하지 않았으면 이런식으로 python이라는 명령어만으로는 실행되지 않는다.

반복 실행

for문

for i in range(3):
    print("로리로리해!")
    print("중딩도 맛있어")
    print("상하기 직전이지만 고딩도 먹을 수는 있지")
    print("대학생 이상은 할망구라구!")

0~2 범위에서 for문을 반복한다. range 안의 숫자는 0부터 n-1까지이다. 왜 0부터냐하면은 C 언어를 비롯하여 컴퓨터에서는 일반적으로 0부터 숫자를 세기 때문이다.

while문

i=1
while i<=7:
    print(i)
    i=i+1
print("Finished!")

그리고 이름은 대충 test.py로 하고, 저장한다. i=1은 i의 초기 값이 1이라는 의미이다. while i<=7:은 i가 7이 될 때까지 반복하라는 의미이다. <=는 작거나 같다는 의미이고, >=는 크거나 같다는 의미이다. i=i+1은 원래 있던 i 값에 1을 더하여 i 값을 1 늘려주라는 의미이다.

그리고 터미널에서 test.py가 있는 디렉터리로 이동 후

python3 test.py

라고 치면 아래와 같은 결과가 뜬다.

1
2
3
4
5
6
7
Finished!

조건문

if문

이제 아래와 같이 지에디트에 적고 test2.py라는 이름으로 저장해보자.

i=0
while True:
    i=i+1
    if i==3:
        print("Skipping 3")
        continue
    if i==7:
        print("Breaking")
        break
    print(i)
print("Finished")

while True:는 while문을 계속 반복하라는 의미이다. True 대신에 1을 써도 된다. 반대로 while False:나 while 0:을 쓰면 while문이 바로 종료되면서 Fihished만 출력되고 끝난다. 하지만 되도록이면 1이나 0 대신에 True와 False를 쓰는 게 좋다. if i==3:은 만약 i가 3이라면 if문을 실행하라는 의미이다. ==는 같다는 의미이다. 프로그래밍에서 =는 같다는 의미가 아니라, 변수를 선언하는 의미이다. 즉, i=0은 i라는 변수에 0을 넣으라는 의미고, i=i+3은 이전의 i 값에 3을 더한 값을 새로운 i 값으로 한다는 의미이다. continue는 if문을 계속 하라는 의미이고, break는 if문을 끝내라는 의미이다.

그리고 터미널에서

python3 test2.py

를 입력하면

1
2
Skipping 3
4
5
6
Breaking
Finished

라고 뜰 것이다.

if, else문

x = int(input("나이를 입력해: "))
if x<=13:
    print("로리로리해!")
else:
    print("중학생 이상은 할망구지!")

x가 13보다 작거가 같을 때는 "로리로리해!"를 출력하고, 그게 아닐 경우에는 "중학생 이상은 할망구지!"를 출력한다. input은 키보드 입력을 받으라는 소리이고, int는 정수값으로 입력을 받으라는 소리이다. 정수, 실수, 문자열 등 여러가지 종류의 입력을 받을 수 있으며 int나 float을 적어놓지 않고

x = input("나이를 입력해: ")

와 같이 적어놓으면 숫자를 적어놓아도 숫자가 아닌 문자열로 입력을 받는다.

정수 int, 실수 float

여기서 int는 괄호 안에 있는 값을 정수로 변환하며 문자열이든 실수든 상관없이 정수로 변환합니다. 물론 문자열의 내용이 숫자(10진 정수)가 아니라면 변환이 되지 않고 에러가 발생합니다. 이점 주의해주세요. int('10')은 10으로, int(3.5)는 3으로 입력을 받지만 int('hello')는 에러가 뜬다.

그럼 실수의 덧셈도 계산할 수 있겠죠? input으로 입력받은 값을 실수로 변환하려면 float로 묶어줍니다.

a = float(input('첫 번째 숫자를 입력하세요: '))    # float를 사용하여 입력 값을 실수로 변환
b = float(input('두 번째 숫자를 입력하세요: '))    # float를 사용하여 입력 값을 실수로 변환
 
print(a + b)

1.2 + 1.5의 결과로 2.7이 나왔습니다. 만약 float를 사용하지 않으면 문자열 '1.2'와 '1.5'가 연결되어 '1.21.5'가 됩니다.

float는 괄호 안에 있는 값을 실수로 변환하며 문자열이든 정수든 상관없이 실수로 변환합니다. 물론 문자열의 내용이 숫자(10진 정수, 실수)가 아니라면 변환이 되지 않고 에러가 발생합니다. 이점 주의해주세요. float('3.5')는 3.5이고, float(10)은 10.0이지만 float('hello')는 오류가 뜬다.

elif 사용

x = int(input("나이를 입력해: "))
if x<=13:
    print("로리로리해!")
elif 13<x<=16:
    print("중딩도 맛있어")
elif 16<x and x<=19:
    print("상하기 직전이지만 고딩도 먹을 수는 있지")
else:
    print("대학생 이상은 할망구라구!")

elif(else if)를 사용하여 조건이 여러개인 조건문을 만들 수 있다.

break로 반복문 끝내기

i = 0
while True:    # 무한 루프
    i += 1     # i를 1씩 증가시킴
    print(i)
    if i == 10:    # i가 10일 때
        break       # 반복문을 끝냄. while의 제어흐름을 벗어남

while문에서 break 사용

for i in range(0, 10000):    # 0부터 9999까지 반복
    print(i)
    if i == 13:    # i가 13일 때
        break       # 반복문을 끝냄. for의 제어흐름을 벗어남

for문에서 break 사용

continue로 코드 실행 건너뛰기

이번에는 continue를 사용하여 일부 코드를 실행하지 않고 건너뛰어 보겠습니다. 다음은 1부터 100까지 숫자 중 짝수만 출력합니다.

for i in range(1, 101):    # 1부터 100까지 증가하면서 100번 반복
    if i % 2 != 0:         # i를 2로 나누었을 때 나머지가 0이 아니면 홀수
        continue           # 홀수일 경우 아래 코드를 실행하지 않고 건너뜀
    print(i)

%는 나누라는 소리이고, ==는 같다는 의미, !=는 같지 않다는 의미이다. A=B는 A에 B를 대입하라는 소리이다.

삼각형 그리기

print('\n'.join(('*'*(2*y-1) for y in range(1,20))))

1부터 N까지 출력

for x in range(int(input("n을 입력해 주십시오: "))):
    print(x+1)

또는

_ = list(print(x+1) for x in range(int(input("n을 입력해 주십시오: "))))

구구단

_ = list(eval(r"print(x, '*', y, '=', x*y, end = ('\n' if y == 9 else ' '))") for x in range(2,10) for y in range(1,10))

99병의 맥주

99병의 맥주(99 Bottles of Beer)는 미국과 캐나다 등에서 자주 불리는 권주가(勸酒歌)이다. 벽장에 있는 99개의 맥주병을 하나씩 꺼내면서 수가 줄어드는 걸 노래하고 있다.

start = 99
def bottles(i, leading):
    if i < 0:
        i = start
    _n = "N" if leading else "n"
    _s = "s" if i != 1 else ""
    _i = str(i) if i != 0 else _n + "o more"
    return _i + " bottle" + _s
take_or_buy = lambda i: "Go to the store and buy some more" if i == 0 else "Take one down and pass it around"
for i in range(start, -1, -1):
    print(bottles(i, True) + " of beer on the wall, " + bottles(i, False) + " of beer.")
    print(take_or_buy(i) + ", " + bottles(i - 1, False) + " of beer on the wall.")
    print("")

함수에서 재귀 호출 사용하기

함수 안에서 함수 자기자신을 호출하는 방식을 재귀 호출(recursive call)이라고 합니다. 재귀 호출은 일반적인 상황에서는 잘 사용하지 않지만 알고리듬을 구현할 때 매우 유용합니다(구현은 만들다와 같은 뜻입니다). 보통 알고리즘에 따라서 반복문으로 구현한 코드보다 재귀호출로 구현한 코드가 좀 더 직관적이고 이해하기 쉬운 경우가 많습니다.

이번에는 재귀호출을 사용하는 방법과 주의점을 알아보겠습니다. 참고로 재귀호출은 코드가 간단한 편이지만 머릿속으로 생각을 많이 해야 됩니다. 그래서 초보자들은 한 번에 이해가 되지 않을 수 있습니다.

먼저 간단한 재귀호출 함수를 만들어보겠습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.

def hello():
    print('Hello, world!')
    hello()
 
hello()

hello 함수 안에서 다시 hello 함수를 호출하고 있습니다. 소스 코드를 실행해보면 'Hello, world!' 문자열이 계속 출력되다가 에러가 발생합니다. 왜냐하면 파이썬에서는 함수 호출 스택의 깊이 제한이 1,000으로 정해져 있어서 그렇습니다. 즉, hello 함수가 자기자신을 계속 호출하다가 스택이 넘쳐서 스택 오버플로우(stack overflow)가 발생합니다.

재귀호출을 사용하려면 반드시 다음과 같이 종료 조건을 만들어주어야 합니다.

def hello(count):
    if count == 0:    # 종료 조건을 만듦. count가 0이면 다시 hello 함수를 호출하지 않고 끝냄
        return
    
    print('Hello, world!', count)
    
    count -= 1      # count를 1 감소시킨 뒤
    hello(count)    # 다시 hello에 넣음
 
hello(5)    # hello 함수 호출

먼저 hello 함수의 반복 횟수를 계산하기 위해 매개변수 count를 지정합니다. 그리고 count가 0이면 hello 함수를 호출하지 않고 끝냅니다. 만약 0이 아니면 'Hello, world!'를 출력하고, count의 값을 1씩 감소시킨 뒤 hello 함수를 호출할 때 넣어줍니다.

이제 hello 함수를 호출할 때 반복할 횟수를 넣어줍니다. 이렇게 하면 hello 함수가 재귀호출을 할 때마다 count에 들어있는 값이 1씩 감소하고, 0이 되면 재귀호출을 끝냅니다.

파이썬 코딩 도장: 33.1 재귀호출 사용하기 https://dojang.io/mod/page/view.php?id=1053

재귀 호출로 팩토리얼 구하기

파이썬에서 팩토리얼(factorial)을 구하는 방법은 여러 가지가 있지만 이번에는 재귀호출을 사용하여 팩토리얼을 구현해보겠습니다. 팩토리얼은 1부터 n까지 숫자를 차례대로 곱한 값이며 !(느낌표) 기호로 표기합니다. 예를 들어 5!은 5 * 4 * 3 * 2 * 1이며 결과는 120입니다.

x = int(input('팩토리얼 계산할 숫자를 넣으세요: '))

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

print(factorial(x))

input을 그냥 사용하면 문자열로 입력을 받으니 정수(integer)로 입력을 받으라는 의미이다. factorial이라는 함수를 정의한다(define). 만약 x가 0이면 1을 돌려준다(return). 그게 아니면 x와 factorial 함수에 x-1을 대입한 것을 곱한다. x가 만약 3이라면 0이 아니니 3과 factorial(2)를 곱할테고, factorial(2)는 2와 factorial(1)을 곱한 것이고, factorial(1)은 1과 factorial(0)을 곱한 것이고, factorial(0)은 1을 돌려주라고 했으므로 뒤에서부터 하나씩 계산해 나가면 1을 돌려주고, 1과 1을 곱하고, 2와 1*1을 곱하고, 3과 2*1을 곱하여 3*2*1=6이 나온다.


GUI 지원되는 소스 코드

GUI(Graphic User Interface) 프로그래밍이란 쉽게 말해 윈도우 창처럼 화면을 보며 마우스나 키보드로 조작할 수 있는 프로그램을 만드는 것이다. 파이썬으로 GUI 프로그램을 만드는 것은 다른 언어를 이용해 만드는 것보다 훨씬 쉽다. 대표적인 예로 파이썬 프로그램을 설치할때 함께 설치되는 기본 모듈인 Tkinter(티케이인터)를 이용해 만드는 GUI 프로그램을 들 수 있다. 실제로 Tkinter를 이용한 파이썬 GUI 프로그램의 소스 코드는 매우 간단하다. Tkinter를 이용하면 단 5줄의 소스 코드만으로도 윈도우 창을 띄울 수 있다. 놀랍지 않은가!

파이썬에는 wxPython, PyQT, PyGTK 등과 같이 Tkinter보다 빠른 속도와 보기 좋은 인터페이스를 자랑하는 것들도 있다. Tkinter는 트킨터 또는 티케이인터라고 읽으면 된다.


자세한 소스 코드는 트킨터(Tkinter) 문서 참조.

실행 가능한 파이썬 스크맆트

파이썬 인터프리터는 보통 /usr/local/bin/python3.6 에 설치됩니다; 유닉스 셸의 검색 경로에 /usr/local/bin 를 넣으면 명령:

python3.6

을 셸에 입력해서 실행할 수 있습니다. 유닉스에서, 파이썬 3.x 인터프리터는 보통 python 이라는 이름의 실행 파일로 설치되지 않는데, 동시에 설치되는 파이썬 2.x 실행 파일과 충돌하지 않도록 하기 위해섭니다. 인터프리터가 위치하는 디렉터리의 선택은 설치 옵션이기 때문에, 다른 장소도 가능합니다; 주변의 파이썬 전문가나 시스템 관리자에게 확인할 필요가 있습니다. 예를 들어, /usr/local/python 도 널리 사용되는 위치입니다.


BSD 스타일의 유닉스 시스템에서 파이썬 스크립트는 셸 스크립트처럼 직접 실행할 수 있게 만들 수 있습니다. 인터프리터가 사용자의 PATH 에 있다고 가정할 때 다음과 같은 줄

#!/usr/bin/env python3.5

을 스크립트의 시작 부분에 넣고 파일에 실행 가능 모드를 줍니다. #! 는 반드시 파일의 처음 두 문자여야 합니다. 일부 플랫폼에서는 이 첫 번째 줄이 유닉스 스타일의 줄 종료 ('\n')로 끝나야 하며, 윈도우 줄 종료('\r\n')는 허락되지 않습니다. 파이썬에서 해시, 또는 파운드, 문자 '#' 는 주석을 시작하는 데 사용됩니다.


스크립트는 chmod 명령을 사용하여 실행 가능한 모드, 또는 권한, 을 부여받을 수 있습니다.

$ chmod +x myscript.py


소스 코드가 유닉스 "셔뱅 (shebang)" 줄 로 시작하는 경우에, 문자 인코딩 선언은 두 번째 줄에 들어갑니다. 예를 들어:

#!/usr/bin/env python3
# -*- coding: cp-1252 -*-

와 같이 해주면 됩니다.


윈도우 시스템에서는 "실행 가능 모드"라는 개념이 없습니다. 파이썬 설치 프로그램은 .py 파일을 python.exe와 자동으로 연결하여, 파이썬 파일을 이중 클릭하면 스크립트로 실행합니다. 확장자는 .pyw일 수도 있습니다. 이 경우, 일반적으로 나타나는 콘솔 창은 표시되지 않습니다.

https://python.flowdas.com/tutorial/appendix.html#executable-python-scripts


라이브러리

인터넷상 Python으로 보급되는 package는 타 어느 스크립트 언어와도 비교가 안될 만큼 다양하다. 당신이 하려는 것이 무엇이든, 무슨 언어를 써야 할지 모르겠으면 Python을 쓰면 된다. Python으로 직접 만들었던지, 다른 프로그램의 wrapper가 꼭 존재한다. 못하는 것이 없다. PyPI 또는 구글 검색을 해보면 안다.

웹 사이트 서버를 구현하려고 하면 python web framework를 쳐보자(Django).

기계 학습 알고리즘을 쓰고 쉽다면 python machine learning 이라 검색하자(scikit-learn).

얼굴 인식을 코드 몇줄로 할 수도 있다(OpenCV).

게임도 만들 수 있다(PyGame). ~~Python make girlfriend도 된다 카더라.~~

뷰티풀 수프(Beautiful Soup)

용도: XML, HTML와 같은 구문 트리 또는 구조화된 데이터 처리.

장점: ‘뷰티플 수프’는 마크업 언어 문서를 처리하는 데 따르는 어려움을 완화해준다. 수프를 사용하면 수작업을 거쳐야 하는 여러 작업이 간소화되며, 특정 항목 또는 특정 유형의 항목을 검색하기도 훨씬 더 쉬워진다. 버전 3은 파이썬 2.x에서만 작동한다. 버전 4에서 파이썬 3 호환성이 추가되고 부팅 성능이 향상됐다. lxml 라이브러리(수프에서 코어로 사용 가능)보다 속도는 느리기는 해도, 많은 사용자들이 lxml을 직접 다루는 것보다 수프를 다루는 것을 더 편안하게 느낀다. 수프는 결함 있는 마크업에도 상당히 관대한데, 이는 스크린 스크래핑(Screen Scraping)을 하거나, 다른 다른 사람이 오래 전에 작성한 결함 있는 코드를 관리할 때 큰 도움이 된다.

필로우(Pillow)

용도: 간편한 이미지 처리

장점: 이미지 처리 경험이 있는 대부분의 파이썬 사용자들은 PIL(파이썬 이미징 라이브러리)에 익숙할 것이다. 그러나 PIL은 은 제약이 많으며, 업데이트가 잦지 않다는 단점이 있다. 필로우는 PIL보다 더 사용하기 쉬우면서도, 최소한의 변경만으로 PIL과의 코드 호환성 확보에 목표를 두고 있다. 네이티브 윈도우 이미징 기능과 파이썬의 Tcl/Tk를 지원하는 Tkinter GUI 패키지를 사용하기 위한 확장이 포함되어 있다. 필로우는 깃허브(GitHub) 또는 PyPI 자료실에서 내려 받을 수 있다.

구이(Gooey)

용도: 콘솔 기반 파이썬 프로그램을 플랫폼 기반의 GUI로 바꾸기

장점: 일반인들은 명령 줄 프로그램에 익숙하지 않다. 어떤 옵션을 사용해야 하는지, 또는 어떤 순서로 입력해야 하는지를 이해하는 것은 정말 어려운 일이다. ‘구이(Gooey)’는 argparse 라이브러리에 사용되는 인수를 GUI 형태로 표현한다. 모든 옵션에 레이블이 붙어 적절한 컨트롤(다중 옵션 항목 제공을 위한 드롭다운 등)과 함께 제공된다. 이미 argparse를 사용하고 있다면, 구이를 이용하기 위해 단 한 개의 include와 데코레이터(decorator, @)를 붙이기만 하면 된다.

스크래피(Scrapy)

용도: 스크린 스크래핑 및 웹 크롤링

장점: ‘스크래피(Scrapy)는 전체 스크랩 과정을 간소화해준다. 스크랩할 항목 유형을 정의하는 클래스를 만들고 해당 데이터를 페이지에서 추출할 방법에 관한 몇 가지 규칙을 작성하면 그 결과를 JSON, XML, CSV 또는 다른 형식으로 내보내준다. 수집된 데이터를 있는 그대로 저장하거나 가져오는 과정에서 필요 없는 부분을 제거할 수 있다. 또한 스크래피는 웹사이트 로그인이나 세션 쿠키 처리와 같은 기타 다양한 작업을 지원하기 위해 확장될 수 있다. 스크래피로 자동 추출된 이미지는 스크랩된 콘텐츠에 연결된다.

셸(Sh)

하위 프로세스에서 외부 프로그램을 호출하고, 그 결과값을 파이썬 프로그램으로 반환하는 용도 – 만약 호출 프로그램이 네이티브 파이썬 함수에도 마찬 가지의 기능이다.

장점: 모든 포직스(Posix) 호환 시스템에서 셸(Sh)는 최고의 선물이다. 이러한 플랫폼에서 제공되는 모든 명령 줄 프로그램을 파이썬 방식으로 사용할 수 있게 해준다. 더 이상 쓸데없는 작업으로 시간을 낭비할 필요도 없고(OS에 이미 있는 ping을 다시 구현할 필요는 없다), 그 기능을 애플리케이션에 추가 하는 방식에 대해 고민할 필요도 없다. 다만 주의 사항은 이 라이브러리를 통해 전달되는 매개 변수는 정제되지 않는다는 점이다. 따라서 사용자 입력을 그대로 전달하지 않도록 해야 한다.

scikit-learn

오픈 소스인 scikit-learn사이킷런은 자유롭게 사용하거나 배포할 수 있고, 누구나 소스 코드를 보고 실제로 어떻게 동작하는지 쉽게 확인할 수 있습니다. scikit-learn 프로젝트는 꾸준히 개발, 향상되고 있고 커뮤니티도 매우 활발합니다. 잘 알려진 머신러닝 알고리즘들은 물론 알고리즘을 설명한 풍부한 문서(http://scikit-learn.org/stable/documentation)도 제공합니다. scikit-learn은 매우 인기가 높고 독보적인 파이썬 머신러닝 라이브러리입니다. 그래서 산업 현장이나 학계에도 널리 사용되고 많은 튜토리얼과 예제 코드를 온라인에서 쉽게 찾을 수 있습니다. 앞으로 보게 되겠지만 scikit-learn은 다른 파이썬의 과학 패키지들과도 잘 연동됩니다.

scikit-learn은 두 개의 다른 파이썬 패키지인 NumPy넘파이와 SciPy싸이파이를 사용합니다. 그래프를 그리려면 matplotlib맷플롯립을, 대화식으로 개발하려면 IPython아이파이썬과 주피터 노트북도 설치해야 합니다.

https://tensorflow.blog/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/1-2-%EC%99%9C-%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%B8%EA%B0%80/#1.3

넘파이(NumPy)

용도: 통계, 선형 대수, 행렬 계산, 금융 운용 등을 포함한 과학 계산과 수학 작업

장점: 금융 시장 분석가나 회계 담당자는 넘파이(NumPy)에 익숙하며, 이를 즐겨 사용한다. 그러나 넘파이의 응용 범위는 수학과 통계를 제외하고도 생각 외로 넓다. 예를 들어 넘파이는 다른 언어를 사용하다 파이썬을 처음 접한 개발자들이 자주 불평하는 파이썬에 다차원 배열 지원을 추가하는 작업을 가장 쉽게, 가장 유연하게 할 수 있는 방법 중 하나다. 다만 모든 요소를 갖춘 완벽한 파이썬 ‘과학-수학’ 기능을 원한다면 넘파이를 표준 항목으로 포함하는 사이파이(SciPy) 라이브러리 및 환경을 사용하는 편이 좋다. 넘파이를 기반으로 하는 정교한 데이터 분석에는 판다스(Pandas)가 있다.

NumPy(http://www.numpy.org/)는 파이썬으로 과학 계산을 하려면 꼭 필요한 패키지입니다. 다차원 배열을 위한 기능과 선형대수 연산과 푸리에 변환 같은 고수준 수학 함수와 유사pseudo 난수 생성기를 포함합니다.

scikit-learn에서 NumPy 배열은 기본 데이터 구조입니다. scikit-learn은 NumPy 배열 형태의 데이터를 입력으로 받습니다. 그래서 우리가 사용할 데이터는 모두 NumPy 배열로 변환되어야 합니다. NumPy의 핵심 기능은 다차원(n-차원) 배열인 ndarray 클래스입니다. 이 배열의 모든 원소는 동일한 데이터 타입이어야 합니다.

SciPy

SciPy(https://www.scipy.org/scipylib)는 과학 계산용 함수를 모아놓은 파이썬 패키지입니다. SciPy는 고성능 선형대수, 함수 최적화, 신호 처리, 특수한 수학 함수와 통계 분포 등을 포함한 많은 기능을 제공합니다. scikit-learn은 알고리즘을 구현할 때 SciPy의 여러 함수를 사용합니다. 그중에서 가장 중요한 기능은 scipy.sparse입니다. 이 모듈은 scikit-learn에서 데이터를 표현하는 또 하나의 방법인 희소 행렬 기능을 제공합니다. 희소 행렬sparse matrix, 희박 행렬은 0을 많이 포함한 2차원 배열을 저장할 때 사용합니다.

matplotlib

matplotlib(https://matplotlib.org/)은 파이썬의 대표적인 과학 계산용 그래프 라이브러리입니다. 선 그래프, 히스토그램, 산점도 등을 지원하며 출판에 쓸 수 있을 만큼의 고품질 그래프를 그려줍니다. 데이터와 분석 결과를 다양한 관점에서 시각화해보면 매우 중요한 통찰을 얻을 수 있습니다. 이 책의 모든 그래프는 matplotlib을 사용했습니다. 주피터 노트북에서 사용할 때는 %matplotlib notebook이나 %matplotlib inline 명령을 사용하면 브라우저에서 바로 이미지를 볼 수 있습니다. 대화식 환경을 제공하는 %matplotlib notebook 명령을 권장합니다(하지만 이 책에서는 %matplotlib inline을 사용합니다).

pandas

pandas(http://pandas.pydata.org/)는 데이터 처리와 분석을 위한 파이썬 라이브러리입니다. R의 data.frame을 본떠서 설계한 DataFrame이라는 데이터 구조를 기반으로 만들어졌습니다. 간단하게 말하면 pandas의 DataFrame은 엑셀의 스프레드시트와 비슷한 테이블 형태라고 할 수 있습니다. pandas는 이 테이블을 수정하고 조작하는 다양한 기능을 제공합니다. 특히, SQL처럼 테이블에 쿼리나 조인을 수행할 수 있습니다. 전체 배열의 원소가 동일한 타입이어야 하는 NumPy와는 달리 pandas는 각 열의 타입이 달라도 됩니다(예를 들면 정수, 날짜, 부동소숫점, 문자열). SQL, 엑셀 파일, CSV 파일 같은 다양한 파일과 데이터베이스에서 데이터를 읽어 들일 수 있는 것이 pandas가 제공하는 또 하나의 유용한 기능입니다. 이 책은 pandas의 기능을 자세히 설명하지는 않습니다. 대신 pandas에 대한 훌륭한 안내서로 웨스 맥키니Wes Makinney가 쓴 『파이썬 라이브러리를 활용한 데이터 분석』(한빛미디어, 2013)을 추천합니다.

텐서플로우(TensorFlow): 머신 러닝

텐서플로우(TensorFlow)는 다양한 작업에 대해 데이터 흐름 프로그래밍을 위한 오픈 소스 소프트웨어 라이브러리이다. 심볼릭 수학 라이브러리이자, 뉴럴 네트워크같은 기계 학습(machine learning) 응용 프로그램에도 사용된다. 이것은 구글내 연구와 제품개발을 위한 목적으로 구글 브레인팀이 만들었고 2015년 11월 9일 아파치 2.0 오픈 소스 라이선스로 공개되었다.

인공 지능(artificial intelligence, AI), 머신 러닝(machine learning), 인공 신경 망(artificial neural network), 딮 러닝(deep learning)에 많이 쓴다.

아래 링크 참조


프레임워크

웹 프레임워크

일반적으로 파이썬을 웹 서비스에 쓴다고 하면 쟁고우(Django, [ˈdʒæŋɡoʊ])나 플래스크(Flask, [flӕsk])를 쓴다고 생각하면 된다. Django는 풀 스택 웹 프레임워크이고, Flask는 아니다.

파이썬과 비슷한 루비(Ruby)에서는 루비 온 레일즈(Ruby on Rails)와 시나트라(Sinatra)라는 웹 프레임워크(web framework)를 많이 쓴다.


풀 스택(full stack)은 처음부터 끝까지 모든 것을 한다는 의미이다. 즉, 풀 스택 개발자면 사용자에게 보여지는 프론트엔드(HTML, CSS, JavaScript 등)부터 서버에서 돌아가는 백엔드(Python, Ruby, PHP 등)까지 혼자서 다 개발하는 사람을 말한다.

풀 스택 프레임워크(framework)는 유저 인터페이스(user interface) 개발부터 데이터 저장(data store) 개발까지 모두 다 도와주는 프레임워크를 말한다. 풀 스택이 아닌 프레임워크는 논 풀 스택 프레임워크(non full stack framework)라고 부른다.

매크로 프레임워크(macro framework)나 매크로 라이브러리(macro library)는 크기가 5 KB가 넘는 것을 말한다. 그것보다 작은 것은 마이크로 프레임워크나 마이크로 라이브러리라고 부른다.

매크로 프레임워크는 모듈라 프레임워크(modular framework)와 모놀리식 프레임워크(monolithic framework 또는 monolith)로 나뉜다. 모듈라는 모듈(module)로 기능이 나눠진 것이고, 모놀리식은 하나의 덩어리로 되어서 일부 기능을 떼어내면 정상 작동을 하지 않는 것이다.

운영 체제하드웨어 위의 커널(kernel), 그리고 그 위의 (shell), 그리고 그 위의 애플리케이션으로 구성된다. 그 중 커널은 모놀리식 커널(monolithic kernel)과 마이크로 커널(micro kernel)이 있는데, 한 덩어리로 되어서 많은 기능을 다 집어넣은 리눅스유닉스의 커널이 모놀리식 커널이며, 미닉스(Minix), 마하(Mach), GNU 허드(Hurd), 심비안의 커널은 마이크로 커널, 그리고 그 둘을 섞은 하이브리드 커널(hybrid kernel)이 있다. 하이브리드 커널은 모놀리식 커널에 마이크로 커널을 포함시킨 것이다. 하이브리드 커널에는 윈도우즈 NT 커널과 macOSiOS의 기반이 되는 다윈XNU 커널이 있다.

Django

쟁고우(Django)는 Python기반 웹 프레임워크(web framework) 중에 가장 널리 퍼져있다. 풀 스택(full stack) 웹 프레임워크(web framework)이다.


자세한 내용은 쟁고우(Django) 문서 참조.

Flask

플래스크(Flask)는 Django와 함께 파이썬에서 많이 쓰이는 웹 프레임워크이다. Django와는 달리 논 풀 스택 웹 프레임워크(non full stack web framework)이다. 즉, 최소한의 기능만 있어서 가볍고 빠르다. 그리고 필요한 기능이 있으면 추가해서 사용한다.

파이게임(Pygame)

용도: 파이썬으로 비디오 게임을 제작하기 위한 프레임워크 장점: 게임 개발 분야에서 일하지 않는 사람이 이러한 프레임워크를 다룰 일이 있을까 라고 생각한다면 오산이다. 파이게임(Pygame)은 캔버스와 그래픽 그리기, 다채널 사운드 처리, 창과 클릭 이벤트 처리, 충돌 감지 등의 복잡한 작업 없이도 여러 가지 GUI 지향 동작을 편리하게 다룰 수 있는 방편을 제공한다. GUI 앱이라고 할지라도, 모든 앱에 파이게임이 제공하는 기능을 적용하지 못할 수도 있다는 사실을 감안하면서, 파이게임의 기능을 한차례 훑어보는 것도 좋다.

토끼와 오소리 게임

참고로 아래 예제는 파이썬 2.7.3으로 작성되어서 파이썬 3와는 조금 안 맞을 수 있다.


  • 10대들을 위한 파이선 게임 프로그램 시작하기

2014.05.22

밑의 글에도 잠시 적기는 했지만 파이선으로 만든 프로그램이 인터랙티브하게 돌아야 할 이유는 많다,

파이선은 빠른 프로토타입이나 리버스 엔지니어링에 좋다고 한다. 쉽게 말하면 나같이 게으른 사람을 위해 만든 언어라고 보아도 좋다.

문제는 이제 이걸로 무엇인가를 해야 하는데 몇가지의 장벽이 있다.

하나는 기계와 다이렉트 io 하는 부분이 약하다는 것이다. c 나 다른 언어로 무엇인가를 해주어야 한다.

펑셔널 어프로치가 아쉽다는 점... 이부분은 람다로 어느 정도 극복 가능하고 정 안되면 리스프나 스킴 인터프리터를 내재해도 된다.

그래픽이나 사운드같은 것이 잘 안된다는 점 .. 이부분을 pygame 같은 것으로 만들어서 놀면 된다는..

오늘은 그래서 파이선 게임을 만드는 예제를 한번 차분하게 번역을 해보기로 했다.

Beginning Game Programming for Teens with Python

글의 제목은 10대들을 위한 파이선 게임 프로그램 시작하기 정도로 번역할 수 있겠다. 더 좋은 이름이 있으면 제게 알려주면 이름을 고치겠다.

원문은 https://www.raywenderlich.com/24252/beginning-game-programming-for-teens-with-python 에서 볼수 있다.

그럼 조금씩 시작해 보자.

이 글은 튜토리얼 팀 멤버인 줄리안 메이어 , 13 세 파이썬 개발자가 적었다. Google+ 와 Twitter 에서 찾을수 있다.

비디오 게임을 만드는 방법이 대다한 것이라고 생각할지도 모르지만 그다지 복잡하지 않다!

이 튜토리얼에서 토끼와 오소리라는 간단한 게임을 만들 것이다. 여기서 히어로인 토끼는 오소리떼의 공격에서 성을 방어할 것이다.

http://toyfab.tistory.com/entry/10%EB%8C%80%EB%93%A4%EC%9D%84-%EC%9C%84%ED%95%9C-%ED%8C%8C%EC%9D%B4%EC%84%A0-%EA%B2%8C%EC%9E%84-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0


멀티쓰레딩 문제

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

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

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

자세히 알고싶다면 다음 링크들을 참조.


파이썬으로 멀티코어 프로그램 만들기

파이썬으로 시도해보는 멀티 코어 프로세싱, 자고 있는 코어들을 깨우기

서버로 프로그래밍을 하다보면 sun grid engine을 사용하여 코어가 4개 이상인 pc cluster를 활용하곤 한다. 20개의 노드에 코어가 24개씩 있으면 job을 480개로 분할해서 하나씩 일을 주는 것이다. 개인용 pc에서는 이런 방법이 통하지 않으니 python의 multiprocessing을 사용해야한다.

파이썬에서는 thread와 multiprocessing이라는 두 가지 내부 모듈이 있는데, 처음에는 이 둘이 어떤 이유로 성능차이를 보이는지 알 수 없었지만 관련 책자들을 찾아보다 보니 그 차이와 활용시점에 대해서 기술되어 있었다.

thread는 CPU보다는 latency time이 있는 일에 효과적이고 multiprocessing은 CPU 의존적인 작업에 활용하는 것에 효과적이다.

따라서 thread를 4개를 쓴다고 해서 CPU 의존적인 작업의 처리에 속도향상이 나타나지 않는다. multiprocessing을 사용해야 다중 코어의 속도향상을 체험할 수 있다.

다중코어를 사용한다고 해서 속도가 선형적으로 증가하는 것은 아니다. 따라서 코어를 8개 동시에 쓰는 작업이 8배의 성능 향상을 가져오지는 못한다. 해당 코어의 효율을 대략적으로 나타낸 그래프는 다음과 같다.

https://philipwfowler.github.io/2015-01-13-oxford/intermediate/python/04-multiprocessing.html

파이썬에서 다중 코어를 쓰는 방법은.. 정말 간단하다.

import multiprocessing as mp

def work(job_list):
    return job_list + 1

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

보통 이런 형태로 만들면 된다. 분할해야할 작업들은 list 안에 하나씩 넣으면 되고, map의 기능을 활용해서 함수에 리스트 요소들을 순차적으로 처리한다.

참고로 windows에서는 맨 아래 추가로 적어두어야 할 코드가 있다.

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

이 한 줄의 넣지 않으면 에러가 나면서 작동되지 않는다. windows에서는 fork()라는 기능이 부족해서 이러한 기능을 사용한다고 해야하는데 자세한 내용은 아직 모른다. 정확하게 얘기하면 리눅스BSD유닉스 계열에는 fork 함수가 있고, 윈도우즈에는 없다.

multiprocessing를 사용하지 않았을 때와 multiprocessing을 사용했을 때 CPU 사용량에 확연한 차이가 있다. 속도는 보통 약 3배정도 차이가 난다. multiprocessing을 사용하지 않는다고 하더라도 CPU가 완전히 single로 작동하지는 않는 것 같다.

아무래도 multiprocessing 하나만 사용했을 때는 속도상의 이점이 크게 느껴지지 않을 수도 있다. numba, cython과 같은 라이브러리를 사용하면 속도가 약 20배 정도 빨라지므로 이 둘을 조합하면 파이썬으로도 만족할만한 성능이 나올 것이다.

https://blog.naver.com/ossiriand/220548193193