2. 파이썬 프로그램의 특징 Last updated: 2023-10-17 10:26:49
파이썬 프로그램은 인터프리터 언어이다. 따라서 따로 컴파일 할 필요 없이 파이썬 명령을 통해 바로 실행할 수 있다. 인터프리터 언어의 특징은 여러 명이 동시에 작업할 때도 장점으로 작용될 수 있다. 각자 작성하는 프로그램이 완성되지 않았더라도 해당 함수를 호출하기 전 까지는 오류가 발생하지 않기 때문에 각자 자신의 영역을 개발하면 된다. 반면 인터프리터 언어는 정의되거나 구현되지 않은 클래스나 함수를 사용하면 컴파일 단계에 오류가 발생하여 단계적 개발을 어렵게 한다.
Note! 컴파일 언어 vs. 인터프리터 언어
컴파일 언어는 소스 코드를 컴퓨터가 이해할 수 있는 바이너리 코드로 변환한 후 이를 실행하는 프로그램을 말한다. 대표적인 컴파일 언어는 C와 Java등이 있다. 이에 반해 인터프리터 언어는 컴파일 없이 소스 코드를 한 줄 씩 읽으며 바로 실행한다. 컴파일 언어에 비해 조금 느리지만 코드가 완벽하지 않아도 정상적인 코드까지는 바로바로 테스트 해볼 수 있고, 컴파일 하는 과정을 거치지 않기 때문에 편리한다. 대표적인 인터프라터 언어로 자바스크립트가 있다.
Note! 파이썬은 진짜 인터프리터 언어인가?
앞에서 이야기 했듯 파이썬은 인터프리터 언어이다. 하지만 파이썬 프로그램을 실행하다 보면 내가 직접 작성하지 않은 .pyc 파일이 생성된 것을 종종 볼 수 있다. 실제로 .pyc 파일은 컴퓨터가 이해할 수 있는 기계어로 된 바이트 코드이다. 다시 말해 컴파일한 결과라는 것이다. 컴파일 언어가 아니라고 했는데 해깔린다.
사실 모든 인터프리터 언어도 실제 컴퓨터가 이해할 수 있도록 사람이 작성한 코드를 기계어로 변환한다. 보통은 이 결과를 메모리에 저장하고 바로 실행하게 되는데, 파이썬은 이 변환 과정의 시간을 절약하기 위해 메모리의 내용을 파일로 저장하고 다음번에 재활용하는 것이다. 그러니 명시적으로 사용자가 컴파일을 할 일은 없다. 다만, 가끔 소스 코드를 수정했는데 이전과 같이 동작하는 것처럼 느껴진다면 .pyc 파일을 지우고 다시 실행해본다. 가끔 파이썬 인터프리터가 소스 코드 변화를 인지 못하는 오류가 발생하기도 한다는 보고가 있다.
파이썬은 코드 작성에 대한 약속이 있고, 많은 라이브러리들이 제공되고 있어 개발하는데 생산성을 높일 수 있다. 파이썬은 다른 언어와 쉽게 결합이 된다. C나 C++언어로 작성된 프로그램을 파이썬에서도 사용할 수 있기 때문에 언어의 확장성이 뛰어나다. 파이썬에서 사용 가능한 라이브러리 중에는 C나 C++등 다른 언어로 익히 알려진 프로그램들이 많이 있다. PyTorch도 원래는 Torch에서 시작된 것이고, Open-CV도 파이썬과 결합되어 Opencv-Python으로 파이썬에서도 사용할 수 있다.
파이썬은 기본적으로 소스 코드를 UTF-8로 인코딩 된 것으로 처리한다. UTF-8은 한국어를 비롯한 다양한 다국어를 지원하는 훌륭한 인코딩 방식이다. 특별한 경우가 아니라면 UTF-8 포맷의 *.py 파일을 생성 후 소스 코드를 작성하면 된다. 만일 특별한 인코딩 방식을 원하는 경우 소스 코드 맨 상단에 다음과 같이 원하는 인코딩 방식을 명시할 수도 있다. 파이썬 코드 인코딩을 지정하는 방식은 다음과 같다.
# -- coding: encoding --
만일 euc-kr 인코딩을 사용한다면 소스 코드 상단에 다음과 같이 작성하면 된다.
[예제 2-1] 파이썬 파일 인코딩 지정하기
# -*- coding: euc-kr -*-
파이썬은 패키지 소프트웨어의 설치와 관리를 위해 pip 프로그램을 주로 사용한다. Java를 사용해 보신 분이라면 Maven이라는 패키지 관리 도구를 사용해 보셨을 것이다. 파이썬은 pip 명령을 이용해 원하는 [패키지를 저장소](https://pypi.org/)에서 직접 다운로드 받아 설치하며, 이 때 설치하는 패키지의 의존성 검사를 통해 함께 설치해야 하는 패키지도 알아서 설치해준다. 때문에 파이썬의 패키지 관리는 다른 언어에 비해 상당히 쉬운 편에 속한다. 또한, 파이썬은 실행을 위한 가상 환경을 쉽게 구성할 수 있고, 이 가상환경 마다 pip 명령을 통해 원하는 패키지를 설치할 수 있어서, 동일한 컴퓨터 환경 내에서도 자유자재로 여러 개발 환경을 구성해 개발 및 운영이 가능한다.
PEP8은 Program Enhance Proposal 8의 약자로 파이썬 프로그램 개선을 위한 제안이다. 다시 말해 파이썬 프로그래밍을 할 때 강력하게 준수해야 하는 코드 스타일 가이드이다. 파이썬 언어는 표준화 된 코딩 스타일을 매우 중요하게 여긴다. 다른 프로그래밍 언어들은 동일한 내용을 구현하는 다양한 방법을 허용하고, 줄바꿈이나 괄호 사용, 주석 처리 등에 대해서도 매우 관대한 정책을 가지고 개발자의 선택에 맡긴다. 하지만 파이썬은 가능하면 파이썬의 코딩 스타일을 지키도록 권고한다. 이는 소스 코드에 대한 가독성을 높여 그만큼 소스 코드가 간결해지고, 타인의 코드를 이해하기도 쉬워지기 때문이다. 이것이 파이썬이 추구하는 방식이다. 따라서 파이썬 코드를 작성하는 파이썬 개발자가 되려고 한다면 파이썬이 추구하는 정신도 받아들여 이해하기를 바란다. - 홈페이지: [https://peps.python.org/pep-0008/](https://peps.python.org/pep-0008/)
• 들여쓰기는 공백 4칸 을 권장한다. 탭을 사용하는 대신 공백 문자 4칸을 사용한다. • 한 줄은 최대 79자를 권장한다. 80자가 넘어가면 줄을 바꿔 작성한다. • 최상위(top-level) 함수와 클래스 정의 앞에는 두 줄을 띄운다. 공백이 더 적거나 많게 하지 않도록 한다. • 클래스 안에서 메소드 정의는 1줄 씩 띄어 쓴다. 물론 함수나 변수를 선언할 때도 각 코드 사이는 최대 1줄의 공백을 사용한다.
* 불필요한 공백은 사용하지 않는다. * 대괄호([ ])와 소괄호(( ))안 * 쉼표(,), 쌍점(:)과 쌍반점(;) 앞 * 키워드 인자(keyword argument)와 인자의 기본값(default parameter value)의 = 는 붙여 쓴다. [표 2] 파이썬에서 권고하는 코드 작성법
권고하는 방식
(1)번
spam(ham[1], {eggs: 2})
(2번) 함수 인자를 입력 시 값이 없더라도 공백 없이 입력
foo = (0,)
spam(1)
(3번) 쉼표는 앞에 변수에 붙여서 공백 없이
if x == 4: print(x, y); x, y = y, x
(4번)
x = 1
y = 2
long_variable = 3
권고하지 않는 방식
(1) 함수 호출 시 괄호() 시작과 끝에 불필요한 공백은 넣지 않는다.
spam( ham[ 1 ], { eggs: 2 } )
(2) 함수 인자 값이 없더라도 공백을 넣지 않는다
foo = (0, )
spam (1)
(3) 쉼표 앞 공백은 불필요
if x == 4 : print(x , y) ; x , y = y , x
(4) 변수 값 대입시 탭이나 공백으로 세로 줄을 맞추는 행위
x = 1
y = 2
long_variable = 3
- 코드와 모순되는 주석은 없느니만 못한다. 항상 코드에 따라 갱신해야 한다. - 불필요한 주석은 달지 않는다. - 한 줄 주석은 신중히 사용한다. - PEP 257 – Docstring Conventions : [https://peps.python.org/pep-0257/](https://peps.python.org/pep-0257/)
변수명에서 밑줄(’_’, underscore)은 위치에 따라 다음과 같은 의미가 있다.
_single_leading_underscore
밑줄로 시작하는 변수는 시스템 내부적으로 사용되는 변수를 의미한다. 따라서 개발자 변수를 선언할 때는 밑줄로 시작하는 변수를 만들지 않는다.
변수를 변수를 선언하면 접근하는 곳에 따라 접근 권한 때문에 해당 변수를 사용할 수 없게 되는데, 파이썬은 이러한 경우 변수명 앞에 밑줄을 추가해 변수명을 변경함으로 접근을 제어한다.
_my_var = 10
single_trailing_underscore_
파이썬 기본 키워드와 충돌을 피하려고 사용한다.
my_var_ = 10
__double_leading_underscore
클래스 속성으로 사용 되면 그 이름을 변경한다. (ex. Car 클레스에 정의된 __model_name 변수는 _Car__model_name 으로 바뀐다.)
__my_var = 100
소문자 L, 대문자 O, 대문자 I는 변수명으로 사용하지 않는다.
어떤 폰트에서는가독성이 굉장히 안 좋다.
모듈(Module) 명은 짧은 소문자로 구성 되며 필요하다면 밑줄로 나눈다.
모듈은 파이썬 파일(.py)에 대응하기 때문에 파일 시스템의 영향을 받으니 주의한다.
C/C++ 확장 모듈은 밑줄로 시작한다.
클래스 명은 카멜 케이스(CamelCase)로 작성한다.
내부적으로 쓰이면 밑줄을 앞에 붙이다.
예외(Exception) 는 실제로 에러인 경우엔 Error를 뒤에 붙이다.
함수명은 소문자로 구성하되 필요하면 밑줄로 나눈다.
대소문자 혼용은 이미 흔하게 사용되는 부분에 대해서만 하위 호환을 위해 허용한다.
인스턴스 메소드의 첫 번째 인자 는 언제나 self이다.
클래스 메소드의 첫 번째 인자는 언제나 cls이다.
메소드명은 함수명과 같으나 비공개(non-public) 메소드, 혹은 변수면 밑줄을 앞에 붙이다.
서브 클래스(sub-class)의 이름 충돌을 막기 위해서는 밑줄 2개를 앞에 붙인다.
상수(Constant) 는 모듈 단위에서만 정의하며 모두 대문자에 필요하다면 밑줄 로 나눈다.
- 코드는 될 수 있으면 어떤 구현(PyPy, Jython, IronPython등)에서도 불이익이 없게 작성되어야 한다. - None을 비교할 때는is나is not만 사용한다. - string모듈보다는 string메소드를 사용한다. 메소드는 모듈보다 더 빠르고, 유니코드 문자열에 대해 같은 API를 공유한다. - 접두사나 접미사를 검사할 때는startswith( )와endwith( )를 사용한다. - 객체의 타입을 비교할 때는isinstance( )를 사용한다. - 빈 시퀀스(문자열, 리스트(list), 튜플(tuple))는 조건문에서 거짓(false)이다. - 불린형(boolean)의 값을 조건문에서 == 를 통해 비교하지 않는다.
하지만 변수가 추가되는 경우에는 어떨까. 변수가 추가 될 때마다 공백을 유지하기 위해 불필요한 변경이 생긴다. 이는 소스를 병합(merge)할 때 혼란을 일으키기 쉽다.
언뜻 보면 잘 이해가 안 가는 규칙은 이런 것도 있다.
[표 3] 파이썬 코드 권고사항
권고한다 | 권고하지 않는다 |
---|---|
import sys import os | import sys, os |
굳이 한 줄 씩 내려쓰면 길어지기만 하고 보기 안 좋지 않을까? 하지만 이 역시 대부분의 변경 추적 도구가 행 기반임을 고려하면 그렇지 않다.