* 바쁘신 분들을 위한 3줄 요약
1. 파이썬은 매우 인기가 높은 프로그래밍 언어입니다.
2. 파이썬은 개발하기 쉬운 인터프리터 언어입니다.
3. 파이썬은 문법이 매우 직관적입니다.
소개 (Introduce)
파이썬(Python)은 프로그래밍 언어로, 1991년에 Guido van Rossum이라는 프로그래머에 의해 만들어졌습니다. python은 현세대의 가장 인기 있는 프로그래밍 언어라 할 수 있습니다. 2023년도 2월 PYPL(PopularitY of Programming Language) index 조사 결과에 따르면 python이 가장 대중적인(popular) 언어로 소개되고 있습니다. 참고로 stack overflow에서는 javascript가 1위, python이 4위에 위치하고 있습니다.
PYPL PopularitY of Programming Language
Worldwide, Feb 2023 compared to a year ago:
Rank | Language | Share |
1 | Python | 27.7 % |
2 | Java | 16.79 % |
3 | JavaScript | 9.65 % |
4 | C# | 6.97 % |
5 | C/C++ | 6.87 % |
6 | PHP | 5.23 % |
7 | R | 4.11 % |
8 | TypeScript | 2.83 % |
9 | Swift | 2.27 % |
10 | Objective-C | 2.25 % |
파이썬이 유명해진 데에는 파이썬의 독특한 문법이 한몫을 했습니다. The Zen of python이라는 글은 파이썬의 문법 특징을 잘 설명해 주는 파이썬 철학입니다.
파이썬의 선 (Zen of Python)
The Zen of python은 파이썬 기여자인 Tim Peters가 파이썬의 설계철학을 널리 알리기 위해 작성했습니다.
필자는 The Zen of python을 통해 python은 가독성을 중요시 하는 언어임을 다시 한번 느끼게 되었습니다.
python 코드가 얼마나 읽기 쉬운지 The Zen of python을 통해 알아보세요
이하 내용은 Zen of Python의 전문입니다.
The Zen of Python, by Tim Peters
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!
인터프리터(Interpreter)
파이썬은 인터프리터(Interpreter) 언어입니다. 인터프리터는 통역하는 프로그램으로, 이를 깊게 이해하기 위해서는 우선 컴파일러(Compiler)를 이해해야 합니다.
컴파일러(Compiler)란? : 번역하는 프로그램. 책을 통째로 번역하는 것과 같다.
사람은 C언어를 사용하고, 컴퓨터는 이진법 언어(Binary code, Hex code, object code, machine code 등)를 사용하기에 서로의 언어를 이해하지 못합니다. 그래서 이를 해결하기 위해 필요한 것이 바로 Compiler입니다. Compiler는 C언어를 기계가 이해할 수 있도록 이진법 언어로 번역합니다. 이런 과정을 거쳐 사람은 C언어를 통해 바로 .exe와 같은 프로그램을 생성합니다.
C++의 Compiler인 g++를 예시로 하여 그림으로 표현해 보았습니다. 한 단계씩 설명해 보겠습니다.
Preprocessing
사람이 작성한 코드를 전처리 합니다. 이때 #include, #define 했던 것들이 코드에 실제로 적용되게 됩니다. 예시 그림을 보시면, Task.cpp는 12줄인데, Task.ii는 3만 줄이 넘어갑니다. 이는 #include <iostream>이 3만 줄이 넘어가기 때문입니다.
전처리 작업이 끝나면. 확장자를 ii로 바꿔줍니다. 이는 더 이상 전처리 하지 않겠다는 표시입니다. 그림에 있는 Task.ii와 Task.cpp를 비교해 보면, #define PLUS + 가 적용되어, sum 함수가 변화되었음을 알 수 있습니다.
Complication
전처리 작업이 끝나면, 본격적으로 코드를 어셈블리(assembly) 코드로 전환합니다. 어셈블리 코드 특징은, 실제 CPU에 있는 하드웨어 명령어와 거의 1:1을 이루는 코드들로 되어 있다는 것입니다. 그렇기 때문에 거의 CPU가 읽기 직전까지 왔다고 생각하면 됩니다.
Assembly
어셈블리 언어를 binary(hex) 코드로 만들어 .o(obj file)에 저장합니다. 이 파일은 CPU가 이해할 수 있는 언어인 machine code로 작성되었으며, 이제는 기계가 읽을 수 있습니다. 하지만, 작성된 코드들이 완전히 하나로 합쳐진 상태가 아닙니다. 코드들이 여러 파일에 걸쳐서 작성되었다면, 하나로 합칠 필요가 있습니다,
Linking
obj file들을 이제 하나로 모으고, Library도 붙이고, OS환경에 맞게 동작하도록 정보를 모으고 모아 .exe(executable file) 파일을 만듭니다. 이 파일은 이제 완전히 프로그래머가 작성한 코드대로 동작합니다. 여기가 사실상 최종 목적지입니다.
(exe 파일은 사실 windows OS의 주된 형식이고, linux의 경우는 보통 .out 확장자를 붙이나, 다른 확장자여도 실행 가능합니다.)
정리하자면, cpp 코드들은 전체 내용을 한 번에 Compiler를 거쳐 machine code가 되며, 컴퓨터는 이 binary code를 읽고 수행하게 되는 것입니다. 저희가 보통 볼 수 있는 .exe 파일들이 바로 컴파일러 언어를 통해 제작되었다는 사실, 알고계셨나요? 컴파일러 얘기는 여기까지 하겠습니다. 이제 인터프리터 얘기를 해볼까요?
인터프리터(Interpreter)란? : 통역하는 프로그램. 대화를 실시간으로 번역하는 것과 같다.
코드의 한 줄씩 기계가 이해할 수 있는 언어로 통역하여 프로그램을 구동합니다.
인터프리터 언어는 사람이 이해하는 코드를 한 줄씩 컴퓨터가 이해하는 언어로 번역하여 실행하게 됩니다.
컴파일러가 코드 전체를 번역한 것과는 차이가 있습니다.
인터프리터는 사람이 이해하는 코드(python, javascript 등)를 한 줄씩 읽어 컴퓨터가 이해하는 언어로 번역한 후, 실행한다는 프로그램을 뜻합니다. C언어는 gcc가, C++언어는 g++가 있는 것처럼, 파이썬 코드를 컴퓨터가 이해할 수 있도록 통역해 주는 대표적인 인터프리터는 CPython이 있습니다.
잠깐, Python은 무엇이고, CPython은 무엇인가요?
* Python : 프로그래밍 언어.
* CPython : C언어로 만들어진 표준 파이썬 인터프리터.
* Python Interpreter : 파이썬을 실행할 수 있는 인터프리터. CPython, Java로 만든 Jython, Python으로 만든 PyPy도 여기에 속한다.
* 사실 위와 같은 단어들은 많이 혼용되어서 사용되기도 한다.
그럼 파이썬 인터프리터는 어떻게 동작할까요? 그림과 함께 살펴봅시다.
Syntax Check, Compilation
인터프리터에게 .py 파일을 실행하라고 하면 먼저 구문부터 오류가 없는지 확인합니다. 구문에 오류가 있다면 raise SyntaxError를 수행하고 종료됩니다. 만약 구문에 오류가 없다면, Compilation을 진행합니다. 인터프리터라서, Compile 같은 동작은 없을 줄 알았는데 Byte code까지는 Compile 합니다. 이 변환된 Bytecode는 Memory로 올라갑니다. 만약에 이 작업을 미리 해두고 싶다면 .pyc 파일로 만들어서 저장할 수 있습니다.
* 즉 .pyc는 .py보다 실행 로딩 속도가 빠르지만, runtime 성능은 동일합니다.
Execute line of Bytecode
Bytecode로 변환이 완료되었으면 실행을 하면 됩니다. 실행은 Bytecode의 한 단위씩 실행을 하게 됩니다. 이 코드는 아직 CPU가 읽을 수 있는 코드가 아니기 때문에 Machine code로 변환이 필요한 단계입니다.
* 역 어셈블러 모듈(dis module)을 사용하면 Bytecode를 어셈블리 언어로 볼 수 있습니다.
Translate to machine code
Interpreter가 Bytecode를 machine code로 변환하여 실행합니다. 이제 python의 한 줄이 실행되었습니다. 이제 다음 Bytecode line을 읽고 변환을 할 준비를 합니다.
* python이 text을 machine code로 한 번에 변환한다고 생각하셨던 분들은, 중간에 Bytecode가 있다는 점을 다시 확인 바랍니다.
장점 (Advantages)
지금까지, 인터프리터가 어떻게 동작하는지를 알아보았습니다. 그럼 어떤 이유로 인터프리터를 사용하는 걸까요?
Interpreter의 장점
1. 하드웨어에 종속되지 않는다 : 컴파일러는 CPU에 따라 어셈블리 언어가 달라져, Hardware의 변화에 민감합니다. 하지만 인터프리터로 개발을 한다면, 인터프리터 자체가 Hardware호환되는 한, 코드는 정상적으로 구동됩니다. 하지만 OS에는 영향을 받으니 주의합시다.
* 그건 컴파일 언어도 마찬가지 아니냐 할 수 있는데... 이는 최종 산출물 관점의 차이입니다. 예를 들어 C++는 보통 exe가 최종 산출물이며, 32bit에서 만들었다면 64bit에서 잘 돌지 않습니다. 하지만 python의 경우는 보통의 경우 .py로 작성된 text 자체가 최종 산출물입니다. 각자의 환경에 python이 있다는 가정하에 배포하기 때문입니다. C로 개발하시는 분이 "나는 C code가 최종 산출물이고 이 코드를 배포하는 것이 최종 목적"이라 하면 하드웨어에 종속되지 않는다고 말할 수도 있습니다만... 흔치 않은 경우입니다. Embedded의 경우만 보더라도 Memory address, GPIO 등 이미 코드 자체가 하드웨어에 종속되어 있습니다. Cross complier (LLVM/Clang 등)를 사용한다면, 지원 H/W 범위가 넓어졌다고 얘기할 수는 있지만, "H/W에 종속되지 않는다"라고 얘기할 수는 없습니다.
* 만약 python code를 Pyinstaller 통해 exe로 만들어 배포하게 된다면, 그때는 얘기가 좀 다릅니다. Pyinstaller를 통해 만들어진 exe는 interpreter가 포함되어 있습니다. interpreter는 프로그램이기 때문에 OS와 하드웨어에 종속됩니다.
2. 디버깅이 쉽다 : 컴파일러는 중간에 멈춰서 테스트 코드를 실행하기 어렵습니다. 하지만 인터프리터 언어는 한 줄 단위로 실행하기 때문에, 실행 중간에 멈춘 후 다른 코드를 넣어서 실행하는 것이 매우 쉽습니다. 이런 원리로 실행 중간에 멈춰서 테스트 코드를 삽입하여 더욱 자세한 디버깅을 손쉽게 할 수 있습니다.
3. 개발이 쉽다 : 위와 같은 장점을 합친다면, 개발 난이도가 전체적으로 줄어들 수 있습니다.
4. 인터프리터 개발이 쉽다 : 여기서 말하는 인터프리터 개발은 CPython과 같은 인터프리터 자체를 개발하는 것을 의미합니다. 컴파일러 개발난이도는 상상을 초월합니다. 하지만 인터프리터는 잘 만들어진 컴파일러 위에서 만드는 프로그램이나 다름없기 때문에, 컴파일러에 비해 비교적 쉬운 난이도를 자랑합니다. 이는 곧 인터프리터 자체의 bug fix나, 요구사항에 대해서 빠른 update가 가능하다는 의미도 됩니다.
인터프리터의 장점이 위와 같다면, 파이썬의 장점은 어떤 것이 있을까요?
python의 장점
1. 방대한 library 지원 : 파이썬을 지원하는 Library도 하나씩 소개해볼 예정입니다.
- numpy : 고차원 행렬 기반 수학, 과학 분야 computing을 위한 라이브러리.
- scipy : numpy 확장 구축된 수학 알고리즘 라이브러리
- matplotlib, seaborn : 그래프 모듈 라이브러리
- opencv-python : image processing, computing vision 라이브러리
- tensorflow : Google에서 개발한 머신러닝 라이브러리
- pyTorch : Facebook에서 개발한 머신러닝 라이브러리
- django : 웹 어플리케이션 서버 프레임워크
- flask, fastAPI : 마이크로 웹 프레임워크
- PyQT : Qt가 바인딩된 GUI 툴킷 프레임워크
- beautifulSoup : HTML, XML 구문분석 라이브러리
* 어떤 풍자에서는 하늘에 뜨기 위해 import antigravity(반중력)를 입력했더니 성공했다고 한다.
2. 보기 편한 문법 : 중괄호{ }로 block을 나누는 대신 Space를 문법으로 차용하는 등, 가독성이 참 좋은 언어입니다.
def main():
a = True ## dynamic typing
b = 2 ## dynamic typing
a, b = b, a ## swap 문법
if a: ## if문에 괄호가 없다.
print("a is True") ## block 단위의 {}괄호가 없다. 대신 space로 block관리
elif b: ## else if를 축약해서 사용한다.
print("b is True")
else:
print("a, b is not True")
if __name__ == "__main__":
main()
3. 코딩 공식 가이드 문서의 존재 : PEP(Python Enhancement Proposal)라는 Python 공식 디자인 문서가 존재합니다. 그 중에 특히 pep-0008문서는 코딩스타일에 대한 내용이 담겨져 있습니다.
*이 문서로 인해, 대부분의 언어가 동일한 스타일로 작성되어, 다른 사람의 코드를 쉽게 분석할 수 있습니다.
비판 (Criticism)
하지만 마냥 좋기만 한 파이썬은 아닙니다. 어떤 점이 비판을 받을까요?
1. 느린 동작 : 단적인 예로, C++이 python보다 적게는 2배, 많게는 30배까지도 성능 차이 납니다.
2. 비 개발자에게 파이썬 산출물을 배포하기가 까다롭다 : 배포받은 사람이 실행하려면 python이 있어야 합니다.
2. 소스코드가 쉽게 공개된다 : 이것은 interpreter의 공통적인 단점입니다.
3. 병렬 프로그래밍이 어렵다 : python의 GIL(Global Interpreter Lock)으로 인해 성능효과를 보기 어렵다.
4. pointer가 없다 : python을 좀 더 깊게 사용하고 싶어도 지원되지 않습니다.
하지만 위의 단점들을 덮을 정도로 python은 수많은 장점을 지니고 있으며, 지금까지도 큰 인기를 자랑하고 있습니다.
* reference
https://en.wikipedia.org/wiki/Python_(programming_language)
https://docs.python.org/3/faq/general.html#why-is-it-called-python
https://pypl.github.io/PYPL.html
https://survey.stackoverflow.co/2022/#most-popular-technologies-language
https://docs.python.org/ko/dev/library/dis.html
'Python > Story' 카테고리의 다른 글
Python - 파이썬의 선(The Zen of python) (0) | 2023.02.10 |
---|