본문 바로가기
카테고리 없음

파이썬에 대한 상세 정보 및 소식 (설치,다운로드,FOR문,딕셔너리)

by 채은아빠 2023. 3. 6.
반응형

 프롬스의 최근 이슈 

파이썬

파이선
Python
개발 단체
Python 소프트웨어 재단 (PSF)
라이선스
PSF 라이선스
최신 버전
3.11.2 (2023년 2월 8일 출시)

1. 개요

 

Life is short, You need Python.인생은 짧다.
당신에겐 Python이 필요하다.
1991년에 발표된 인터프리터 방식의 프로그래밍 언어.다.

 

2. 상세

 

창시자는 네덜란드의 프로그래머 귀도 반 로섬(Guido van Rossum). 1989년 크리스마스 주에, 연구실이 닫혀있어서 심심한 김에 만든 프로그래밍 언어이다.
농담이 아니고 반 로섬을 유럽에서는 애덤 스미스에 비교할 정도며, 네덜란드에서는 기술자의 대명사로 취급된다.
심심해서 만들었다는 것은 Python 서문과 마이크로소프트웨어와 한 인터뷰를 보면 알겠지만 사실이다.
능력 있는 기술자들은 대부분 심심할 때, 혹은 실수로 걸작을 만든다.
그리고 Python이라는 이름은 귀도가 즐겨 보던 영국의 6인조 코미디 그룹 몬티 Python에서 따왔다고 한다.
문법이 매우 쉬워서 초보자들이 프로그래밍을 할 때 추천되는 언어이다.
오죽하면 Python의 별명이 "실행할 수 있는 의사 코드(Executable pseudocode)"일 정도. 학습용으로 좋은 언어인 동시에 실사용률과 생산성도 높은 대단히 강력한 언어인 셈. Python 소프트웨어 재단(PSF)에서는 공식 문서로 Python 개선 제안(PEP)이라는 것을 작성하고 있다.
글 작성 순서에 따라 PEP 8, PEP 20과 같이 번호를 붙인다.
이는 Python 코드의 일관성과 발전 방향의 통일을 위해 작성하는 것으로, 이 PEP는 Python 커뮤니티에서는 성경 내지는 법전과 같은 존재로 자리 잡고 있다.
이렇게 명확한 코딩 가이드를 제공한다는 점은 다른 언어들과 확실히 구분되는 점이다.
온라인 상으로 실행시켜 보고 싶다면 여기로.다.

 

3. 특징

 

 

3.1. 디자인 철학

 

'가장 아름다운 하나의 답이 존재한다'를 기본으로 하고 있다.
예를 들어 팩토리얼 함수는 다음과 같이 간결히 나타낼 수 있다.
이 예시에서는 프로그래밍 초보자들을 헷갈리게 하는 3항 연산자(Ternary operator)도 쉽게 읽혀 Python의 "실행할 수 있는 의사 코드"라는 별명을 다시금 느낄 수 있다.
def factorial(x): return 1 if x == 0 else x * factorial(x - 1) 이것은 남이 작성한 코드를 내가 읽고 이해해야 하는 경우 아주 절실히 느낄 수 있다.
PEP 20에서 제시된 Python 기본 철학(The Zen of Python)에 자세히 나열되어 있다.
아름다운 것이 추한 것보다 낫다.
(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!)따라서 다른 언어들의 코딩 스타일은 각자의 취향에 맞게 발산 진화하는 반면, Python은 위의 철학들을 만족시키는 하나의 스타일로 수렴 진화하는 성향이 있다.
이런 성향은 다른 언어에는 없는 Python스러움(pythonic)이라는 독특한 개념을 낳게 되었는데, 복잡하지 않으면서 의미가 명확하고, 코드의 축약보다 뚜렷하게 보이는 흐름을 중시하는 Python의 철학을 지칭하는 개념이다.

 

3.2. 뚜렷한 권장 코드 스타일

 

종류
규칙
예시
패키지(package)
스네이크()
 
모듈(module)
스네이크()
import module_name
클래스(class)
파스칼()
class ClassName()
예외(exception)
파스칼
 
함수(function)
스네이크()
def function_name()
상수(constant)
대문자+밑줄
MODULE_CONSTANT_NAME = 0
변수(variable)
스네이크
variable_name = 0
매개변수(parameter)
지역변수
인스턴스 변수(instance variable)
메서드(method)
스네이크()
method_name()
  • 블록 처리 규칙보통 다른 언어에서는 중괄호를 블록 단위로 사용하지만, Python에서는 중괄호 대신 들여쓰기를 사용한다. 이 들여쓰기 문법 때문에 PEP 8에 명시된 공식 코딩 가이드에서는 소스 코드 들여쓰기에 탭(Tab) 문자 대신 공백(Space) 4문자를 넣기를 매우 강력히 권장한다. 탭 문자는 사용자나 시스템의 설정에 따라 서로 다른 폭의 공백이 생긴다. 문제는 Python 인터프리터가 탭 문자 하나를 공백 1문자로 처리한다는 것이다. 탭 문자로 들여쓰기를 처리하면 자신과 다른 탭 설정을 가진 편집기에서 코드를 열어 볼 경우 코드 들여쓰기가 높은 확률로 망가져 버리고, 그걸 교정해 보겠다고 들여쓰기에 공백 문자를 혼용하는 순간 해당 소스 코드는 사람이 고칠 수 없는 형태로(시각적으로는 블록이 맞지만 Python 인터프리터는 다른 블록으로 인식) 망가져 버린다. 물론 이렇게 스페이스 바를 네 번이나 치는 귀찮은 행위를 프로그래머들이 가만 놔둘 리가 없다. PyCharm, VSCode 등 Python 개발자들이 애용하는 최신 편집기는 탭 키 누르면 공백 4개로 자동 변환되어 입력되는 기능이 지원되므로 이들 편집기를 이용하면 공백 4개를 번거롭게 칠 필요가 없어진다.def factorial(x): if x == 0: return 1 else: return x * factorial(x - 1)
  • 작명 규칙Python에서는 변수나 클래스 이름을 어떻게 짓든 잘 작동한다. 그렇지만 PEP 8 에서는 이에 대한 권장 스타일도 명시하고 있다. Python을 코딩할 때에는 가독성을 위해 이 권장 스타일을 따르는 것이 좋다.아래는 이름에 대한 대표적인 스타일 가이드이다. 일반적으로 스네이크 표기를 쓰되, 특정한 종류에는 파스칼 표기를 쓴다. 표기법은 코딩 스타일 참고.변수는 소문자로 시작하며 , 내부변수(internal)는 맨 앞에 밑줄(underbar, _) 1개로 시작하며, 숨은변수(hidden)은 밑줄 2개로 시작한다.attribute_name = 0_protected_attribute_name = 0__hidden_attribute_name = 0종류규칙예시패키지(package)스네이크()모듈(module)스네이크()import module_name클래스(class)파스칼()class ClassName()예외(exception)파스칼함수(function)스네이크()def function_name()상수(constant)대문자+밑줄MODULE_CONSTANT_NAME = 0변수(variable)스네이크variable_name = 0매개변수(parameter)지역변수인스턴스 변수(instance variable)메서드(method)스네이크()method_name()
  • 일반적으로 스네이크 표기를 쓰되, 특정한 종류에는 파스칼 표기를 쓴다. 표기법은 코딩 스타일 참고.
  • 변수는 소문자로 시작하며 , 내부변수(internal)는 맨 앞에 밑줄(underbar, _) 1개로 시작하며, 숨은변수(hidden)은 밑줄 2개로 시작한다.attribute_name = 0_protected_attribute_name = 0__hidden_attribute_name = 0
  • attribute_name = 0
  • _protected_attribute_name = 0
  • __hidden_attribute_name = 0
  • 문법 규칙아래는 권장되는 대표 유형이다.한 줄은 79글자로 제한하기import는 파일의 맨 위에 적고 내장 모듈, 제3자 모듈, 직접 만든 모듈 순서로 불러들이기인스턴스 메서드의 첫 인자는 self로 쓰고, 클래스 메서드의 첫 인자는 cls로 쓰기할당 연산자(=)의 앞뒤로 공백 넣기
  • 한 줄은 79글자로 제한하기
  • import는 파일의 맨 위에 적고 내장 모듈, 제3자 모듈, 직접 만든 모듈 순서로 불러들이기
  • 인스턴스 메서드의 첫 인자는 self로 쓰고, 클래스 메서드의 첫 인자는 cls로 쓰기
  • 할당 연산자(=)의 앞뒤로 공백 넣기

 

3.3. 순수 객체 지향

 

Python에는 원시 타입(Primitive Type)이 존재하지 않으며, 모든 것이 객체로 취급된다.
나아가 클래스, 함수 역시 객체로 취급할 수 있다.
상수 역시 상수가 저장된 객체라고 본다.
다음과 같은 상수 할당문이 있을 때,x = 10이는 변수 x 자체에 10이 할당된 것이 아니라 x가 10이 저장된 상수 객체를 가리키는 것을 의미한다.
내부적으로는 C의 포인터 연산과 같은 동작이 행해지는 것이다.
이렇게 x에 대입되는 값을 변경할 경우,x = 10 x = 20x가 가리키는 대상이 10이 저장된 상수 객체에서 20이 저장된 상수 객체로 바뀐 것이다.
x 자체의 값이 10에서 20으로 바뀐 게 아니다.
Python 버전 3의 표준 타입 계층 구조에서 주요 자료형은 그림과 같다.
이 중에서도 크게 불변 객체(Immutable Object)와 가변 객체(Mutable Object)로 나눌 수 있다.
불변 객체에는 숫자, 문자열, 바이트, 그리고 튜플이 있다.
이 네 가지를 제외한 나머지 객체는 모두 가변 객체이며, 값을 수정할 수 있다.
불변 객체의 값을 수정할 때는 바뀐 값이 저장된 새로운 객체를 생성하고 참조 대상을 새 객체로 옮기는 식으로 동작한다.
이와 같은 특징 때문에 Python은 순수 객체지향 언어라고 할 수 있고, 이와 같은 순수 객체 지향 언어의 또 다른 예로는 Ruby가 있다.
다만 객체 지향 언어라는 표현은 주의해서 사용할 필요가 있다.
객체 지향은 어디까지나 프로그래밍 패러다임이므로, Python이 객체 지향 언어임은 프로그램 작성이 항상 객체 지향으로 이루어진다는 의미는 아니다.
대부분 처음 Python을 배울 때는 절차 지향적으로 프로그래밍을 하게 되며, 심지어 함수형 프로그래밍도 할 수 있다.
함수의 매개 변수로 불변 객체를 넘겼냐 가변 객체를 넘겼냐에 따라서 함수 바깥에 있는 인자의 값도 수정할 수 있는지 없는지가 달라진다.
불변 객체를 넘겼으면 값의 복사만 일어나고 함수 바깥에는 영향을 주지 못하므로 '값에 의한 호출(Call by Value)'이 될 것이며, 가변 객체를 넘겼으면 함수 바깥에까지 영향을 줄 수 있으므로 '참조에 의한 호출(Call by Reference)'이 될 것이다.
Python 공식 문서에서는 Python의 인자 전달 방식을 '할당에 의한 호출(Call by Assignment)', 또는 '객체 참조에 의한 호출(Call by Object Reference)'이라고 명시하고 있다.

 

3.4. 반복 가능한 객체

 

Python의 가장 큰 특징 중 하나. Python은 반복 가능한 객체(iterable)라는 강력한 기능을 제공한다.
이 객체는 집합, 문자열, 리스트, 튜플, 딕셔너리, 그리고 함수까지도 반복이 가능하며, 이것을 for 구문에서 사용할 수 있게 해준다.
리스트와 튜플 등은 좀 편해지는 정도라 할 수 있지만, 함수의 값을 반복할 수 있다는 것은 큰 장점이다.
그 예로 n의 배수를 구하는 f(n) 함수가 있을 때,def f(n): x = 1 while True: yield n*x x += 1 ot = f(2) print(ot) print(next(ot)) print(next(ot))와 같은 함수를 만드는 것도 가능하다.
함수를 호출하고 나서도 함수가 완전히 끝나기 전까지는 지역 변수가 남아있으며, 함수가 끝나야 지역 변수가 삭제된다.
따라서 함수를 호출할 때마다 x의 값이 증가한다.
이렇게 만들어진 반복 가능한 객체는 __next__ 함수나 next(객체) 함수, 또는 for ... in 객체와 같은 문법들을 이용하여 순서대로 값을 호출할 수 있다.
특히 제너레이터의 경우, 미리 만들어놓는 게 아니라, 호출 될 때 반환값을 새로 만들어 반환하는 방식이기 때문에 메모리 관리 면에서도 이점이 있다.

 

4. 장점

 

 

4.1. 빠른 개발 속도

 

xkcd 353화 옛날 만화라 지금과는 다른 부분이 있는데, Python 3.0부터는 print "Hello, World!"라고 쓰면 오류가 발생한다.
이제는 print("Hello, World!")라고 써야 한다.
참고로 저 만화는 Python 내에 이스터 에그로 삽입되기도 했다.
import antigravity로 antigravity 모듈을 불러오면 나온다.
영상Python의 아이덴티티. 높은 생산성은 그 무엇과도 비교할 수 없는 Python만의 특징이다.
전 세계의 모든 프로그래밍 언어 중에서 Python 정도의 낮은 난이도를 가지면서, 오만가지 분야에서 생산된 훌륭한 패키지들을 통해 범용성까지 갖춘 프로그래밍 언어는 찾기 힘들다.
Python으로 만든 프로그램을 같은 객체 지향 프로그래밍 언어인 Java나 C++로 만드려는 순간 숨이 턱 막힐 정도. 이런 언어들을 사용하려면 설계부터 난감해진다.
인터프리터 언어이면서 우수한 자료형과 다양한 모듈 등을 제공해 개발 기간이 단축되는 것이 특징. Python이 막 유행을 타기 시작했을 때에는 'C언어로 2년 동안 완성하지 못한 프로젝트를 Python으로 한 달 만에 해냈다'는 극적인 경험담이 커뮤니티에 돌았을 정도다.
당장 Python의 집합 자료형 같은 경우 C언어로 구현하려고 하면 머리가 아파 온다.
C언어와의 접착성도 좋기 때문에, 일단 Python으로 빨리 구현하고, 남은 시간에 속도에 병목이 되는 부분을 C++로 전환하는 전략을 내세우고 있다.
버전이 올라가면서 Python 자체도 그리 느리지 않게 되었다.
심지어 어셈블리어 같은 저수준 언어(Low level)도 Python에서 호출할 수 있다.
Python은 어지간한 다른 프로그래밍 언어들을 지원하는 호환성 덕분에 응용할 곳이 무궁무진하다.
실행 속도만 빼고개발 속도가 빠른 데에는 친절한 Traceback도 한몫한다.
코드를 실수로 잘못 짠 곳이 있다면, 어떤 스택을 통해 어떤 어떤 파일의 어떤 줄에서 어떤 함수에서 어떤 종류의 문제가 발생했는지 아주 자세하게 알려준다.
스택을 전부 보여주기 때문에 초보자에게는 당황스러울 수 있지만, 디버깅을 하다 보면 정말 편리하다.
아래는 오류(Exception) 발생 시의 터미널 출력 예시다.
Traceback (most recent call last): File "/path/to/example.py", line 4, in greet('Chad') File "/path/to/example.py", line 2, in greet print('Hello, ' + someon) NameError: name 'someon' is not defined Python 가지고 스프레드시트나 데이터베이스까지 만드는 괴수들도 있다.
Python으로 SQL을 구현하는 건 불가능하다는 소리가 있었지만 우리의 Nerd들은 해내고 말았다.
2013년 Python으로 관리하는 DB 개념이 잡힌 이후 수많은 피드백 끝에 2015년 도전 성공. 심지어 2017년 프랑스의 중견기업에서 Python DB 프로젝트를 보더니 정말로 회사의 DB를 Python으로 관리하는 사업을 벌려서 DB화되지 못하고 저장되던 회사 내부의 파일형 자료들과 기존의 DB에 저장된 자료를 접합시키는 사업까지 했다 한다.
빠른 아이디어 구현이 생명인 연구소에서 각광을 받고 있고, 인스타그램, 유튜브, reddit 등이 Python을 주로 쓰고 있다고 알려져 있으며, 외국의 구인 사이트에도 Python을 할 줄 아는 사람에 대한 수요가 많다.
컴퓨터 관련이 아닌 이공계 전반에서 많이 쓰이는 MATLAB은 오픈소스가 아니라는 점이 최근 추세와 맞지 않아 입지가 좁아지고 있다.
CG 업계에서도 사실상 표준으로 사용되는 스크립트 언어이다.
MEL, MAXScript 등 프로그램별로 자체 스크립트 언어들이 난립하고 있었는데, 현재는 Python 스크립팅을 주력으로 밀고 있다.
동적 타입 언어(Dynamically typed language)라는 점이 큰 프로젝트에서는 단점으로 작용하여 자료 구조 설계나 디버깅이 어렵다는 지적도 있다.
다만 "정적 타입 vs. 동적 타입" 논쟁은 서로의 장단점이 있으며 일종의 종교 논쟁으로 취급받는다.
일례로 OCaml 같은 강력한 타입 인터페이스(Hindley-Milner, System F 등)를 가진 경우, 모든 타입 에러(!)를 컴파일 타임에 잡아낼 수 있는 반면에, 모든 버그가 타입 에러는 아니기 때문에 여전히 테스트 및 디버깅 과정은 필요하며, 타입 시스템으로 인한 부담 때문에 빠른 구현에는 부담이 될 수 있다.
반면에 동적 언어는 빠른 구현의 이점이 있지만 타입 에러가 많이 나는 특징이 있다.
한마디로, 컴파일 언어의 경우에는 컴파일 시간에 잡아낼 수 있는 오류를 범하게 된다는 소리. Python으로 parser를 많이 작성해 봤다면, 십중팔구 읽은 숫자를 string으로 저장했다가 나중에 연산을 했더니 연산이 불가능하다면서 에러가 나거나 이상한 결과가 나온 경험이 있을 것이다.
Python 3.5부터는 Type Hints를 이용해서 변수가 가질 수 있는 타입을 지정할 수 있게 되어 성능 향상에 도움은 안 되지만 가능한 오류를 쉽게 찾아낼 수 있게 되었다.

 

4.2. 피드백의 용이성

 

디자인 철학 자체가 가장 완벽한 하나의 아름다운 해답을 찾는 Python 특유의 철학을 찾다 보니, 문법 자체가 딱 떨어지게 표현된다.
이 때문에 다른 사람이 제안하고 만든 프로그램을 수많은 사람들이 보고 쉽게 접근할 수 있다.
Perl 같은 경우는 Write Once, Read Never라고 불릴 정도로 피드백과는 담을 쌓았는데, Python은 문법이 통일되어 있다 보니 Write Once, Read Infinitely가 되어버렸다.
그래서 프로그램 하나 만들면 다른 프로그래머들에 의해 엄청난 양의 피드백이 들어오게 되었고, 이는 곧 생산성 향상으로도 이어졌다.
괜히 Python이 시간이 갈수록 점유율이 상승하는 언어가 아닌 것이다.

 

4.3. 과학 및 공학 친화성

 

Python은 과학과 공학 분야에서 필요한 여러 기능을 기본적으로 제공한다.
우선 언어 자체적으로 64비트를 넘어가는 매우 큰 정수를 지원한다.
또한 허수를 기본적으로 지원하며, 표준 라이브러리의 decimal, fractions 모듈을 사용해 소수점과 유리수를 정밀하게 다룰 수 있다.
따라서 이러한 기능을 다루는 암호학과 통계 분야에서 쓰기에 알맞다.
Python 생태계 또한 공학 및 과학 분야를 빵빵하게 지원한다.
복잡한 수치와 큰 데이터를 다루는 연산에 알맞은 NumPy, SciPy, pandas, 데이터를 그래프로 시각화하는 Matplotlib, 코드와 데이터를 함께 다룰 수 있는 Jupyter Notebook 등의 강력한 패키지와 도구들을 무료로 사용할 수 있다.
이 점 때문에 막대한 라이센스 비용을 지불해야 하는 MATLAB은 이들에게 밀려 현재 교육용 정도로만 사용되고 현업에서는 거의 도태되고 말았다.
Python 개발자들도 이러한 사실을 잘 알고 있기 때문에 언어 차원에서 관련 패키지를 위한 기능을 제공한다.
가령 Ellipsis (...) 상수는 사실상 NumPy 전용의 슬라이스 객체로 제공한다.
또한 3.5부터는 행렬곱을 위한 @ 연산자가 추가되었다.

 

4.4. 거대한 생태계

 

Python으로 무언가를 하고 싶어지면 그걸 하기 위한 패키지는 인터넷 어딘가에는 반드시 존재한다.
사실상 못 하는 것이 없다.
웹사이트 서버를 구현하려고 하면 Python Web Framework를 쳐보자(Django, Flask 등). 기계학습 알고리즘을 쓰고 싶다면 python machine learning이라 검색하자(scikit-learn, TensorFlow, PyTorch). 얼굴 인식을 코드 몇 줄로 할 수도 있다(OpenCV). 기본적으로 설치되는 모듈인 tkinter 모듈을 이용하면 간단한 GUI 프로그래밍을 할 수 있다.
게임도 만들 수 있다(Pygame). 비주얼 노벨도 만들 수 있다.
(렌파이) 수많은 VFX 프로그램들은 오래 전부터 Python을 스크립트 언어로 채택하고 있으며, 별도의 표준이 존재한다.
프로그래밍에 문외한인 사람도 잠깐만 배우면 엑셀 자동화, 파일 처리 자동화, 웹 크롤링 자동화, 3D 모델링 자동화와 같이 업무 시간을 단축해 주는 프로그램을 아주 쉽게 만들 수 있다.
물론 이 외에도 자동화하거나 만들 수 있는 것들은 끝없이 많다.
다만 모바일 앱 개발에는 리액트 네이티브, 코틀린, 플루터 등이 통용되며 Python을 기반으로 한 프레임워크는 찾기가 쉽지 않다.

 

4.5. 교육의 편의성

 

Python은 위의 특징 때문에 교육용 프로그래밍 언어로 각광받고 있다.
현재 세계 유수의 대학교들은 프로그래밍 개론에서 쓰이는 언어를 C, C++나 Java에서 Python으로 바꾸었다.
주의할 점은 Python이 배우기 쉽다는 건 프로그래머 입장에서 나온 말이라는 것이다.
그마저도 다른 언어에 비해 비교적으로 쉽다는 뜻이지, 깊게 파고들어 가거나 특유의 'Python스러운'(pythonic) 코딩을 하려면 생각보다 신경 쓸 것도 많고 동적 언어에 익숙해져 있어야 한다.
더욱이 컴파일러 없이 프로그래밍 하는 것은 깡초보에게 권장할 만한 것이 아닌게, 정적 언어에 대한 개념도 없이 동적 언어를 잡았다가는 오히려 더 헷갈릴 수 있다.
왜 마이크로소프트가 TypeScript를 만들었는지 잠시 생각해 보기 바란다.
더욱이 Python은 편집증이 의심될 정도로 객체 위주로 돌아가긴 하지만, 언어의 패러다임을 보면 절차 지향, 객체 지향, 함수형 모두 사용할 수 있는 언어다.
극단적으로 OOP를 지향하는 Java나 C보다 더 신경 써야 할 것이 많다는 이야기. 하여튼 프로그래밍 자체를 마냥 쉬운 것으로 생각하다면 큰코다친다.
프로그래밍을 쉽게 할 수 있는 것과 좋게 하는 것에는 큰 차이가 있으며, '좋은' 프로그래밍을 하는 것은 프로그래머의 '역량'에 크게 좌우된다.

 

4.6. GPGPU 기반의 병렬 연산

 

구글 코랩이나 jupyter notebook을 이용한 로컬 및 네트워크 GPU 기반 병렬 연산에 용이한 것도 큰 장점이다.
머신러닝에서 파이썬이 대세가 된 주요 원인이기도 하다.

 

5. 단점

 

 

5.1. 느린 실행 속도

 

우선 기본적으로 가장 아쉬운 점은 속도이다.
한 논문에 따르면, CLBG에서 제시한 10개의 벤치마킹을 돌려본 결과 Python은 C에 비해 71.90배의 시간, 2.80배의 메모리, 75.88배의 에너지를 더 소모한다고 한다.
느린 속도를 보완하기 위해서 보통 여러 가지 방법이 동원된다.
기본적으로는 Python 내장 모듈을 사용해서 멀티쓰레딩이나 멀티프로세싱을 구현한다.
다만 Python은 락 인터프리터 문제로 애초에 멀티프로세싱에 효율적인 타입이 아니다.
즉 싱글프로세싱이 오히려 처리용량은 더 많을 수 있다는 얘기. 혹자는 Scipy나 Numpy와 같은 모듈의 고속 계산 함수를 별도로 개발해 쓰기도(Vectorize) 한다.
더 나아가서는 속도가 빠른 C와 같은 언어를 래핑(Wrapping)하여 작성하기도 한다.
전문적으로 개발할 때는 외부 패키지에 의존하지 않고 직접 작성한 코드에서 고속화를 하기 위해 자연스럽게 더 높은 난이도의 언어를 혼합해서 개발하게 된다.
이 경우 Python은 논리적인 부분을 담당하고, 래핑된 다른 언어는 코어를 담당하게 된다.
사실 전문적인 개발회사라면 이게 일반적이다.
대표적인 예시로 Numba나 Cython같은 제3자 솔루션을 이용하기도 하며, 흔히 인공지능 용도로 사용된다고 오해받는 Python TensorFlow 는 사실 C++ 이다.
Python 을 이용해 TensorFlow 를 '호출도' 할 수 있을뿐이다, TensorFlow 의 로직을 수정 및 커스텀 하기 위해선 반드시 C++ 코드에 손을 대야 한다.
이처럼 Python은 사실 다른 언어에 비해 많이 느리기 때문에 프로그래밍 대회서 컴파일 시간 제한 때문에 어려움을 겪기도 한다.
시스템을 건드리거나 반복 연산이 많은 것은 하기 어렵지만 python numpy 처럼 따로 모듈을 지원하기 때문에 크게 걱정할 필요는 없다.
하지만 python numpy을 사용해도 느린 건 느리다.
결국 Python은 첫 교육용 언어로는 몇달 좋으나 어느정도 튜토리얼을 벗어나려면 C언어를 이용해야 한다는 이야기. 아예 C언어부터 시작하는 것이 낫다는 관점도 존재한다.
GIL(Global Interpreter Lock)은 Python의 성능 저하를 얘기할 때 빼놓을 수 없다.
Python은 멀티쓰레딩을 지원하기 위하여 GIL을 도입하여 사용하게 되었다.
따라서, python 쓰레드 10개를 만들어도 실제 Pthread/윈도우 쓰레드가 10개가 만들어지긴 하는데, GIL 때문에 개중 동시에 하나밖에 안 돌아가는 기이한 구조를 갖고 있다.
물론, 내부적으로 IO작업이 있을 시 바로 다른 쓰레드로 문맥 교환을 해주고, 바이트 코트를 100번 실행한 다음에는 인터프리터 차원에서 다른 쓰레드로 교체해 주므로 동시 작업 비슷한 효과가 난다.
이것은 구현이 매우 쉬워지고 빠른 개발을 할 수 있다는 장점이 있으나, 다중 코어 CPU가 보편화된 2006년 이후에는 다중 코어를 제대로 활용하지 못하는 구조적인 문제 때문에 HW를 이용하지 못한다는 평가를 받게 되었다.
만일 특정 프로그램에 순진하게 CPU 코어를 2개 이상 동원하려고 할 경우, 뮤텍스(MutEx), 즉 한 쓰레드에 여러 개의 CPU가 연산을 행하여 내부 정보를 오염 시키는 것을 방지하는 역할을 맡는 GIL이 병목 현상을 일으켜 코어 하나를 쓸 때보다 오히려 성능이 크게 저하된다는 것. 구글 내부에서 이미 가루가 되도록 까인 부분이다.
다만 GIL은 멀티프로세싱에서는 해당되지 않는 이야기다.
멀티프로세싱 모듈은 메모리를 완전히 분리해서 사용하기 때문이다.
일반적으로 기계어로 컴파일하여 사용하는 C, C++보다는 당연히 느리고, Lua, JavaScript, LISP 계열 언어 등 동적 언어들을 전체를 주욱 놓고 비교해 봐도 속도가 빠른 편은 아니다.
Python처럼 가상 머신 위에서 실행되는 Java, JavaScript 등의 언어들의 경우, 속도 문제를 극복하기 위해서 JIT 컴파일러를 도입했다.
Python의 사실상의 표준 구현체인 CPython은 JIT 컴파일을 도입하지 않았고, JIT 컴파일을 도입한 별도의 구현체인 PyPy가 등장했다.
통계 분야 등 특정 분야에서는 R과 같이 그 분야에 특화된 언어를 사용하는 것이 더 편리할 수도 있다.
더불어, 예전의 Python에는 CPU-bound한 쓰레드가 I/O-bound한 쓰레드와 함께 돌아갈 때, I/O-bound한 쓰레드가 실행되어야 할 상황에서도 context switch가 제대로 이루어지지 않는 문제가 있었다.
이 때문에 CPU-bound 쓰레드가 GIL을 지나치게 오래 점유하게 되면서 I/O 반응 속도가 느려지고, 다른 쓰레드는 GIL을 획득하려고 계속 시도하느라 CPU 시간을 낭비하게 되었다.
이에 대해 Python 전문가인 David Beazley가 2009년에 Mindblowing Python GIL이라는 강연에서 지적하였다.
이후 Antoine Pitrou라는 개발자가 GIL을 뜯어고쳐 해당 문제를 해결하였고, Python 3.2부터는 새로운 GIL이 적용되어서 성능이 어느 정도 개선되었다.
단, CPU 부하가 큰 작업을 돌리는 것이 아니면 GIL을 체감하기는 생각보다 쉽지 않다.
다중 쓰레딩으로 CPU의 여러 코어를 최대한 이용하고 싶은 경우에는 GIL가 굉장히 아쉬운 이슈지만, CPU를 별로 쓰지 않거나 I/O가 주가 되는 작업은 유의미한 성능 차이가 없다.
게다가 어설프게 코어 몇 개 깔짝깔짝 이용해서 계산하는 것보다는 그냥 C언어로 모듈을 짜서 붙이는 게 더 빠르다.
즉, python에서 CPU를 많이 먹는 부분은 C 모듈을 짜서 붙이거나, 이미 C 모듈로 짜여있는 라이브러리를 사용하거나(Numpy, Scipy 등), 필요하다면 multiprocessing 모듈을 이용하여 멀티코어를 활용하는 편. 그 이상의 CPU-heavy한 작업은 처음부터 C, C++로 짜는 게 맞다.
하지만 대규모 연산의 멀티코어의 성능 향상을 보기 위한 것 말고도, I/O가 주가 되는 작업(즉, 여러 개의 I/O 이벤트를 기다리는 것)을 위해서 멀티쓰레드를 사용하는 경우가 많고, 이런 경우에도 복잡한 동기화를 해야 하는 멀티쓰레딩을 사용하는 건 낭비이다.
왜냐하면 디버깅도 힘들 뿐만 아니라, 실제로는 I/O를 위해 기다리는 시간이 실제 I/O가 발생했을 때 필요한 처리 작업을 수행하는 시간보다 월등히 긴 경우가 많아 여러 개의 쓰레드를 관리하기 위한 자원만 낭비하는 꼴이기 때문이다.
따라서 Go나 Erlang 같은 프로그래밍 언어들은 코루틴이란 개념을 도입해 이러한 "event multiplexing"을 싱글쓰레드로도 구현할 수 있게 하고 있다.
특히 멀티쓰레딩할 때 필요한 각종 동기화 문제 없이 마치 싱글 쓰레드 코드를 짜는 것과 거의 동일한 방식으로 코드를 작성할 수 있으면서도 그러한 코드들이 "동시에" 동작하는 것처럼 실행해 주므로 프로그래머 입장에서 매우 편하다.
실제로는 각 이벤트에 필요한 처리를 하고 다음 이벤트가 발생하기 전까지 비는 시간에 다른 이벤트를 처리하는 코드를 실행시켜 주는 방식으로, 시분할과 비슷하지만 문맥 전환이 프로그래머가 작성한 코드에서 명시적으로 다음 이벤트를 기다려야 할 필요가 있을 때 협력적으로 발생한다는 차이점이 있다.
C 같은 언어에서 이러한 코루틴 지원이 잘 안 되는 이유는, 언어적 차원에서 함수 중간에 실행을 멈추고 다른 함수를 실행할 수 있게 해줘야 하는데 쓰레드 별로 stack이 1개밖에 없는 구조에서는 구현이 어렵고 하나의 함수로 짜야 할 내용을 여러 개의 callback 함수로 쪼개면 코드가 지저분해진다는 단점이 크기 때문이다.
이런 callback 형태를 사용하는 게 Node.js 개발 환경이다.
현재로써는 이런 콜백 방식이 유연하면서 퍼포먼스가 좋은 방식이지만 언어적으로 약간 더럽다.
위에서 기술한 Stackless Python에서 코루틴을 먼저 지원할 수 있었던 것도 이런 배경이 있다.
그나마 C++은 C++20에서 지원하기 시작했다.
다행히 Python은 (stackless가 아니더라도) yield 키워드를 통해 함수 실행 흐름을 제어할 수 있다.
Python 3.4 버전부터는 표준 라이브러리의 각종 파일 입출력, subprocess, socket 통신 등의 기능들을 모두 코루틴화해 주는 asyncio 패키지가 기본 탑재되었다.
Python 3.5 부터는 C를 본딴 async 함수 선언자와 await 키워드가 포함되어 asyncio 라이브러리에 의존할 수밖에 없던 코루틴 기능을 다른 서드파티 라이브러리도 보다 쉽게 지원할 수 있도록 바뀌고, 코루틴 내부에서의 예외 처리 과정이 개선되었다.
요새는 특정 경우를 제외하면 자동으로 GIL을 on/off시켜 주는 것으로 보인다.
이렇게 속도를 빠르게 하려고 별별 방법을 동원한다는 것과 이를 잘 아는 사람이 드물다는 것을 감안하면, Python의 최대 단점은 기본적으로 속도가 느리다는 것과 이를 개선하기가 어렵다는 것이라고 할 수 있겠다.
이로서 파생된 문제점으로 Python에 입문하는 것은 쉽지만 마스터하긴 어렵다는 문제점이 발생한다.
이는 프로그래밍 입문만 Python으로 하고 다른 언어를 주력으로 배우고 쓰는 것으로 해결될 수도 있지만, Python은 C 패밀리와 이질적인 문법으로 인해 다른 프로그래밍 언어를 배우는데 별 도움이 안된다는 새로운 문제가 생긴다.
당연하겠지만 Python 언어 자체를 구현하는 사람들도 느린 실행 속도가 Python의 최대 단점이라는 사실을 인식하고 있고 이를 개선하기 위해 다양한 방면에서 연구를 진행하고 있다.
후술할 PyPy와 같이 JIT컴파일을 하는 구현체를 만든 것도 그 결과물 중 하나이며, 최근에는 공식적이자 가장 호환성이 높은 CPython의 속도 또한 개선되고 있다.
Python 창시자 귀도 반 로섬은 2021년 Python 회담(Python Language Summit)에서 버전 3.11에서는 속도를 2배 향상시키고, 향후 4년간은 속도를 5배 향상시키는 것이 목표라고 말했다.
실제로 2022년에 발표된 Python 3.11 버전에서는 상당한 속도 개선이 이루어진 것으로 보인다.
문제는 개선되었다고는 하지만 그래도 다른 프로그래밍 언어들과 비교하면 여전히 느리다는 것과 속도가 개선되는데 한계가 있다는 것이다.
이 때문에 미래에도 속도 개선이 지속적으로 이루어져야 쓸만한 속도가 나올 것으로 보인다.

 

5.2. 일반 사용자에게의 배포

 

 

 

6. Python 구현체들

 

영어로는 Python Implementations이다.
Python은 Python 소프트웨어 재단에서 만들고 관리하는 언어로서 이를 각 운영체제에서 돌리기 위한 표준 런타임도 같은 단체에서 제작한다.
그러나 성능, 확장성 등 다양한 이유로 같은 Python 코드를 다른 방식으로 돌리기 위한 비표준 구현체들도 다양하게 개발되어 있다.
비표준 구현체들은 반복 계산, 특수한 환경에서는 유용할지 모르나 일반적인 용도로 사용하기에는 제약이 많다.
스스로 모든 코딩을 한다면 모르지만 다양한 패키지들을 불러들어 사용할 때에는 예상치 못한 오류를 잔뜩 마주하게 되기 때문이다.
Python 패키지들은 CPython이라는 표준 구현체를 기준으로 제작되어 다른 구현체에서는 구조적으로 실행 자체가 불가능한 경우도 있다.

 

6.1. CPython

 

Python 소프트웨어 재단에서 만드는 표준 Python 구현체다.
보통 말하는 Python이 바로 이것이다.
C로 구현되어 있다.
그냥 부를 땐 Python이라고 쓰고, 다른 구현체와 구분하여 언급할 때는 CPython이라고 표기한다.
공식 GitHub 리포지터리에서 소스 코드를 확인할 수 있다.
현재 Python의 창시자인 귀도와 Microsoft는 서로 협력해서 기존의 CPython을 거의 5배 이상 빨라지게 만드는 것을 목표로 CPython을 최적화하는 작업을 진행 중이다.
위에서도 단점으로 지적되었던 Python 특유의 느린 실행 속도를 어떻게든 개선해보려는 것으로 보인다.

 

6.2. Pyston

 

C++로 구현된 Python 런타임이다.
2021년 기준으로는 리눅스에서만 사용 가능하다.
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 버전이 공식적으로 지원이 중단될 예정이라서 완전하게 돌아가게 되는 시점(이조차 아무도 알 수 없었다)에서 이 프로젝트의 의미가 많이 퇴색될 수밖에 없었던 것.Dropbox는 Pyston에서 PyPy로 옮겼다가 현재는 Go를 쓰고 있다.
Dropbox Tech Blog: Open Sourcing Our Go Libraries (July 1, 2014)홈페이지다.

 

6.3. 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를 사용하면 된다!가상머신에서 동작하는 구현체이다.
이렇게 시작부터 CLR 위에서 동작하는 Python 구현체를 도입하는 경우는 매우 드물다.
그래서 기존에 Java에서 개발되어 운영되던 프로그램이나 시스템이 존재하고, 이 환경 하에서 Python의 간결하고 편리한 기능과 높은 생산성을 도입하고자 할 때에만 사용된다.
CPython에 비하면 실행 속도가 매우 느리다.
따라서 주요 기능을 수행하는 데에는 문제가 있지만, 보조 기능에서 사용하면 번거로운 작업들을 매우 손쉽게 Python 스크립트로 Java의 자원을 그대로 끌어다 써서 할 수 있기 때문에 개발 공수와 편리함에서 큰 장점이 있다.

 

6.4. IronPython

 

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

 

6.5. Brython

 

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

 

6.6. Transcrypt

 

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

 

6.7. MicroPython

 

홈페이지공홈에서 제공하는 웹 에뮬레이터Python3의 기능을 임베디드 보드에 최적화하여 구현한 프로그래밍 언어이다.
Windows OS와 Windows Embeded OS와의 관계를 생각하면 이해하기 쉽다.
국내에서는 주로 마이크로비트보드에서 사용할 목적으로 많이 사용된다.
카시오 FX-9860 GIII에 탑재되어 있기도 하다.
다만 퍼포먼스적인 문제가 심각하게 있는데 아두이노 등의 다른 프레임워크와 비교할 경우 눈에 띄게 느리고 마이너한 모습을 보여준다.
경쟁 플랫폼으로는 아두이노, .NET NANO 등이 있다.
다.

 

6.8. RustPython

 

홈페이지프로그래밍 언어 Rust를 사용하여 구현된 인터프리터이다.
CPython의 많은 표준 라이브러리가 구현되어 있고, 아직 미비하지만 JIT 컴파일 또한 제공한다.
다만 아직 개발 초기 단계이기 때문에 지원하지 않는 기능이 꽤 있으며, 성능상의 이점 또한 적은 편이다.

 

7. 개발 환경

 

 

내용이 도움이 되셨으면 공감 버튼 꼬옥 눌러주세요 

반응형

댓글