파이썬이 해석되면 .pyc 파일이란 무엇입니까?


1083

파이썬이 통역 된 언어라는 것을 이해하게되었습니다 ...
그러나 파이썬 소스 코드를 보면 .pycWindows가 "컴파일 된 파이썬 파일"로 식별되는 파일을 볼 수 있습니다.

이것들은 어디로 오나요?


3
정당화에 대해서는 stackoverflow.com/questions/11433579/… 를 참조하십시오 . 한마디로 : 속도.
user7610



파이썬조차도 Java와 마찬가지로 '한 번 작성하고 어디에서나 실행하십시오'라는 의미입니까?
Mrak Vladar

2
@MrakVladar Java조차도 "한 번 쓰고, JVM이있는 곳이라면 어디에서나 실행할 수 있습니다". 파이썬도 다르지 않습니다. "파이썬 가상 머신이있는 곳이면 어디든 실행할 수 있습니다". 가장 큰 차이점은 대부분의 Python 구현은 컴파일러와 인터프리터를 javaand와 같이 분리하지 않고 하나의 실행 파일로 결합한다는 것 javac입니다.
chepner

답변:


660

여기에는 바이트 코드가 포함되어 있는데, 이는 파이썬 인터프리터가 소스를 컴파일하는 것입니다. 이 코드는 파이썬의 가상 머신에 의해 실행됩니다.

파이썬의 문서는 다음과 같은 정의를 설명합니다 :

파이썬은 컴파일 된 언어와 달리 해석되는 언어이지만 바이트 코드 컴파일러의 존재로 인해 구별이 모호해질 수 있습니다. 즉, 실행 파일을 명시 적으로 작성하지 않고 소스 파일을 직접 실행할 수 있습니다.


10
재미 있네요 그렇다면 파이썬은 순전히 해석 된 언어로 간주됩니까?
froadie

194
@froadie : 언어는 "통역"또는 "컴파일"되지 않습니다. 특정 구현은 인터프리터 또는 컴파일러 (또는 하이브리드 또는 JIT 컴파일러) 일 수있다.
Joachim Sauer

30
'컴파일 된'한 가지 테스트 : 실제 머신 명령어로 컴파일 되었습니까? 파이썬 바이트 코드는 기계 명령어가 아니며 Java 'JVM'명령어도 아니므로 이러한 언어 중 어느 것도 해당 정의에 의해 컴파일되지 않습니다. 그러나 둘 다 중간 '추상 기계'코드로 '컴파일'되었으며 소스 코드 (구식 BASIC이 수행하는 것)를 직접적으로 해석하여 프로그램을 실행하는 것보다 훨씬 빠릅니다.
greggo

20
'컴파일 된'이란 의미는 '번역 된'을 의미합니다. 그런 다음 파이썬은 바이트 코드 로 컴파일 됩니다. AFAIK, Bash 만 실제로 해석되며 다른 모든 인기있는 "해석 된"언어는 모두 바이트 코드로 컴파일됩니다.
bfontaine

13
사실, 그들은 있는 기계 명령어, 그냥 기본 호스트의 물리적 CPU에 대한 기계 명령어는. 따라서 왜 우리는 그것을 VM이라고 부릅니까? 실제로 어셈블리 언어에 대한 에스페란토처럼. 오늘날 우리는 가상의 (그러나 여전히 에뮬레이션 된) CPU (모장의 관심을 끌기위한 모장의 노력)에 대한 원시 코드를 가지고 있습니다. Rexx는 진정으로 해석되었거나 해석 될 수 있으며 BAT와 CMD (및 DCL)는 해석됩니다.
mckenzm

994

파이썬은 통역 언어라는 것을 이해하게되었습니다 ...

이 대중적인 밈은 틀리거나 오히려 (자연적인) 언어 수준에 대한 오해에 기초하여 만들어졌습니다. 이와 비슷한 실수는 "성경은 두꺼운 표지의 책"이라고 말하는 것입니다. 그 직유를 설명하겠습니다 ...

"성경"은 책의 분류 (실제, 물리적 대상) 라는 의미에서 "책"입니다 . "성경의 사본들"로 식별 된 책들은 공통의 근본적인 내용을 가지고 있어야합니다 (내용은 비록 다른 언어로도 수용 될 수있는 번역, 각주 수준 및 주석이 다른 언어 일 수도 있지만). 기본적으로 고려 되지 않는 무수한 측면, 즉 바인딩의 종류, 바인딩의 색상, 인쇄에 사용 된 글꼴, 그림이있는 경우, 쓰기 가능한 여백이 있는지 여부, 숫자 및 내장 된 책갈피의 종류 등이 완전히 다릅니다. 등등.

성서 의 전형적인 인쇄는 실제로 하드 커버 제본 일 가능성이 높습니다. 결국이 책은 일반적으로 여러 곳에서 읽거나 여러 곳에서 책갈피를 지정하고 주어진 챕터 및 구절 포인터를 찾아서 표시하는 책입니다. 등을 사용하면 좋은 하드 커버 바인딩을 사용하면 해당 사본을 더 오래 사용할 수 있습니다. 그러나 이것들은 실제 책의 실제 사본이 성서의 사본인지 아닌지를 결정하는 데 사용할 수없는 일상적인 (실제적인) 문제입니다 : 페이퍼 백 인쇄가 완벽하게 가능합니다!

마찬가지로, 파이썬은 언어 구현 클래스를 정의한다는 의미에서 "언어"입니다. 언어 구현 클래스는 일부 기본 측면 (구문, 명시 적으로 다르게 허용되는 부분을 제외한 대부분의 의미론)에서 모두 유사해야하지만 완전히 허용됩니다. 제공된 소스 파일을 처리하는 방법, 소스를 일부 하위 레벨 형식으로 컴파일하는지 여부 (그러한 경우 어떤 형식)로 저장하는지 여부 등 모든 "구현"세부 사항이 거의 다름 컴파일 된 양식, 디스크 또는 다른 곳으로), 해당 양식을 실행하는 방법 등.

고전적인 구현 CPython은 간단히 "Python"이라고도합니다. 그러나 Microsoft의 IronPython (CLR 코드 (예 : ".NET")으로 컴파일되는 Jython과 함께 여러 프로덕션 품질 구현 중 하나 일뿐입니다. (JVM 코드로 컴파일), PyPy (Python 자체로 작성되고 "Just-In-Time"생성 기계 언어를 포함하여 다양한 "백엔드"형식으로 컴파일 할 수 있음). 그것들은 모두 피상적으로 다른 많은 책 객체가 모두 성경이 될 수있는 것처럼 파이썬 (== "파이썬 언어의 구현")입니다.

CPython에 관심이있는 경우 : 소스 파일을 Python 특정 하위 레벨 양식 ( "바이트 코드"라고 함)으로 컴파일하고 필요할 때 자동으로 수행합니다 (소스 파일에 해당하는 바이트 코드 파일이없는 경우 또는 바이트 코드 파일은 소스보다 오래되었거나 다른 Python 버전으로 컴파일됩니다. 일반적으로 바이트 코드 파일을 디스크에 저장하여 나중에 다시 컴파일하지 않도록합니다. OTOH IronPython은 일반적으로 CLR 코드 (디스크에 저장하거나 저장하지 않음)로 컴파일하고 Jython을 JVM 코드에 저장합니다 (디스크에 .class저장하거나 저장하지 않는 경우 확장명 을 사용함 ).

이 하위 레벨 양식은 "통역사"라고도하는 적절한 "가상 머신"(CPython VM, .Net 런타임, Java VM (일명 JVM))에 의해 실행됩니다.

따라서 C #과 Java가 다음과 같은 경우에만 이런 의미에서 (일반적인 구현이하는 일) 파이썬은 "통역 된 언어"입니다. 모두 바이트 코드를 먼저 생성 한 다음 VM / 인터프리터를 통해 실행하는 일반적인 구현 전략을 가지고 있습니다 .

아마도 컴파일 과정이 얼마나 "무겁고"느리고 높은 예식인지에 초점이 맞춰질 것입니다. CPython은 가능한 한 적은 식으로 가능한 한 빠른 속도로 가능한 빨리 컴파일되도록 설계되었습니다. 컴파일러는 오류 확인 및 최적화가 거의 없으므로 메모리를 소량의 메모리에서 빠르게 실행할 수 있습니다. 대부분의 시간에 컴파일이 진행되고 있음을 사용자가 알 필요없이 필요할 때마다 자동으로 투명하게 실행됩니다. Java 및 C #은 일반적으로 오류를보다 철저하게 확인하고 더 많은 최적화를 수행하기 위해 컴파일 중에 더 많은 작업을 수용하므로 자동 컴파일을 수행하지 않습니다. 검은 색이나 흰색이 아닌 연속적인 그레이 스케일입니다.


2
아름다운 대답. 마지막 단락을 약간만 수정하면 파이썬 은 가능한 빨리 컴파일하도록 설계되었습니다. 이번에는 정적 유형 시스템과 물건이 부족한 언어입니다. 사람들이 "통역 된"언어에 대해 이야기 할 때, 일반적으로 "동적"언어를 의미합니다.
Elazar

1
@Elazar, 실제로, PyPy와 같은 다른 Python 구현은 컴파일을 서두르지 않고 정적 타이핑 부족으로 필요한 철저한 분석을 수행하고 기계 코드에 대한 적시 컴파일을 생성합니다 (따라서 속도 향상) 장기 실행 프로그램을 여러 번 실행).
Alex Martelli

Cython은 어디에 적합합니까? 다른 언어로 생각 하시겠습니까 아니면 파이썬 구현입니까? 또한 파이썬의 VM은 종종 "통역사"라고 불리기 때문에 "해석 된"vs 컴파일 된 용어 혼동일까요? JVM 또는 .NET 런타임 인터프리터를 호출하는 것만 큼 유효합니다. 둘 다 바이트 코드를 JIT 머신 코드로 해석합니다 (일부 캐싱 최적화 예외 포함)
Davos

181

통역 언어와 같은 것은 없습니다. 인터프리터 또는 컴파일러 사용 여부는 순전히 구현 의 특성입니다. 언어와는 전혀 관련이 없습니다.

마다 언어는 인터프리터 나 컴파일러로 구현할 수 있습니다. 대부분의 언어에는 각 유형마다 하나 이상의 구현이 있습니다. (예를 들어, C 및 C ++에 대한 인터프리터가 있으며 JavaScript, PHP, Perl, Python 및 Ruby에 대한 컴파일러가 있습니다.) 게다가 현대 언어 구현의 대부분은 실제로 인터프리터와 컴파일러 (또는 여러 컴파일러)를 결합합니다.

언어는 일련의 추상 수학 규칙입니다. 통역사는 언어에 대한 몇 가지 구체적인 구현 전략 중 하나입니다. 이 두 가지는 완전히 다른 추상화 수준에서 산다. 영어가 입력 언어 인 경우 "통역 언어"라는 용어는 유형 오류입니다. "Python은 해석 된 언어"라는 문장은 단지 거짓이 아닙니다 (거짓 인 경우에도 문장이 의미가 있음을 암시하기 때문에 의미가 없습니다) . 언어는 결코 다음과 같이 정의 될 수 없기 때문에 의미 가 없습니다. "해석"

특히 현재 존재하는 Python 구현을 살펴보면 다음과 같은 구현 전략이 사용됩니다.

  • IronPython : DLR 트리로 컴파일 한 다음 DLR이 CIL 바이트 코드로 컴파일합니다. CIL 바이트 코드는 어떤 CLI VES에서 실행 중인지에 따라 달라 지지만 Microsoft .NET, GNU Portable.NET 및 Novell Mono는 결국 네이티브 머신 코드로 컴파일합니다.
  • Jython : 핫 코드 경로를 식별 할 때까지 Python 소스 코드를 해석 한 다음 JVML 바이트 코드로 컴파일합니다. JVML 바이트 코드는 어떻게 실행중인 JVM에 따라 달라집니다. Maxine은 핫 코드 경로를 식별 할 때까지 최적화되지 않은 네이티브 코드로 직접 컴파일 한 다음 최적화 된 네이티브 코드로 다시 컴파일합니다. HotSpot은 먼저 JVML 바이트 코드를 해석 한 다음 핫 코드 경로를 최적화 된 머신 코드로 컴파일합니다.
  • PyPy : PyPy 바이트 코드로 컴파일 한 다음, 핫 코드 경로를 식별 할 때까지 PyPy VM에 의해 해석되어 핫 코드 경로를 식별 한 다음 실행중인 플랫폼에 따라 고유 코드, JVML 바이트 코드 또는 CIL 바이트 코드로 컴파일됩니다.
  • CPython : CPython 바이트 코드로 컴파일 한 다음 해석합니다.
  • Stackless Python : CPython 바이트 코드로 컴파일 한 다음 해석합니다.
  • Unladen Swallow : CPython 바이트 코드로 컴파일 한 후 핫 코드 경로를 식별 할 때까지 해석 한 다음 LLVM IR로 컴파일하고 LLVM 컴파일러는 네이티브 머신 코드로 컴파일합니다.
  • Cython : Python 코드를 이식 가능한 C 코드로 컴파일 한 다음 표준 C 컴파일러로 컴파일
  • Nuitka : Python 코드를 머신 종속 C ++ 코드로 컴파일 한 다음 표준 C 컴파일러로 컴파일합니다.

해당 목록의 구현 중 하나 (그리고 tinypy, Shedskin 또는 Psyco와 같이 언급하지 않은 일부 구현)에는 컴파일러가 있음을 알 수 있습니다. 사실, 내가 아는 한, 현재 순수하게 해석 된 파이썬 구현은 없으며 그러한 구현도 계획되어 있지 않으며 그러한 구현은 없었습니다.

"해석 된 언어"라는 용어는 "해석 된 구현의 언어"를 의미하는 것으로 해석하더라도 이해가되지 않을뿐만 아니라 사실이 아닙니다. 당신에게 말한 사람은 분명히 그가 무슨 말을하는지 모릅니다.

특히, .pyc보고있는 파일은 CPython, Stackless Python 또는 Unladen Swallow에 의해 생성 된 캐시 된 바이트 코드 파일입니다.


5
MSBASIC과 같은 구식 기초는 중간 형태가 없었습니다. 프로그램은 소스 형식 (또는 가까운 소스, 키워드가 1 바이트 토큰으로 표시되고 행 번호는 2 바이트 2 진 정수로 표시되지만 나머지는 ASCII 임)에서 직접 해석되었습니다. 따라서 실제로 'goto'는 일치하는 대상을 찾기 위해 검색해야하는 소스 라인 수에 따라 다른 시간이 걸립니다. a * b-2 * cos (x)와 같은 표현식은 실행될 때마다 효과적으로 다시 구문 분석되었습니다.
greggo

4
@greggo : 더 오래된 학교로 가고 싶다면 BASIC 의 원래 버전은 기본 코드 컴파일러였습니다. 이것은 "컴파일 된"또는 "통역 된"언어의 개념이 얼마나 우스운지를 증명해야합니다.
Jörg W Mittag

다양한 파이썬 컴파일러 / 통역가 동작하는 방식을 설명해 주셔서 감사합니다. 효율적인 C 또는 JavaScript를 아직 생성하는 훌륭한 Python 컴파일러가 있는지 궁금합니다. 대량 소비가 아니라 적어도 파이썬의 합리적인 하위 집합에 대해서는 가능할 것 같습니다. 또한 Cython이 무엇인지 궁금합니다.
personal_cloud

Cython 은 SciPy 2009에서 언급되었지만 2010 년에 다시 알지 못했기 때문에 용서 할 수 있습니다 (여기서는 2017 년에 단지 지금 배우고 있습니다). 그럼에도 불구하고 우리는 자바 스크립트 예제를 찾을한다고 ... 자이 썬은 나에게 아무 의미가 (2009 년 이미 죽어 자바하지 않았다 음, 음, 아마 ... C ++ 부스트가 너무 좋아 다시 그때 아니었다?)하게
personal_cloud

1
@ personal_cloud : 나는 당신의 의견을 따르지 않습니다. 예, 물론 Cython에 대해 알고 있지만 이것이 무엇과 관련이 있습니까? 그것은 파이썬의 구현이 아니며 완전히 다른 언어입니다. 또한 JavaScript 예제를 찾는 것은 어렵지 않습니다. 실제로 현재 존재하는 모든 주류 JavaScript 구현에는 컴파일러가 있습니다. 마지막으로 Jython은 다른 Python 구현과 마찬가지로 Python 구현입니다. Java 플랫폼의 다른 언어 구현과 마찬가지로 Java 플랫폼의 언어 구현입니다.
Jörg W Mittag

61

이것들은 .py파일을 가져올 때 Python 인터프리터에 의해 생성되며 가져온 모듈 / 프로그램의 "컴파일 된 바이트 코드"를 포함합니다. 소스 코드에서 바이트 코드로의 "번역"(한 번만 수행하면 됨) 파일 이 해당 파일 보다 최신 import이면 후속 s 에서 건너 뛸 수 있으므로 시작 속도가 약간 빨라집니다. 그러나 여전히 해석됩니다..pyc.py


10
진실. 많은 핵심 파이썬 라이브러리가 C로 작성되는 것을 제외하고는 파이썬 실행의 일부가 해석되고 일부는 C에서 실행됩니다. 성능에 민감한 코드 비트와 동일한 작업을 수행 할 수 있습니다.
bwawok

44

모듈 로딩 속도를 높이기 위해 Python은 컴파일 된 모듈 내용을 .pyc에 캐시합니다.

CPython은 소스 코드를 "바이트 코드"로 컴파일하고 성능상의 이유로 소스 파일이 변경 될 때마다 파일 시스템에이 바이트 코드를 캐시합니다. 컴파일 단계를 무시할 수 있기 때문에 파이썬 모듈의 로딩이 훨씬 빨라집니다. 소스 파일이 foo.py 인 경우 CPython은 소스 바로 옆의 foo.pyc 파일에 바이트 코드를 캐시합니다.

python3에서 Python의 가져 오기 메커니즘은 모든 Python 패키지 디렉토리 내의 단일 디렉토리에서 바이트 코드 캐시 파일을 작성하고 검색하도록 확장되었습니다. 이 디렉토리는 __pycache__라고합니다.

모듈로드 방법을 설명하는 순서도는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

자세한 내용은:

참조 : PEP3147
참조 : "컴파일 된"Python 파일


38

이것은 초보자를위한 것입니다.

파이썬은 스크립트를 컴파일하기 전에 바이트 코드라고하는 컴파일 된 코드로 자동 컴파일합니다.

스크립트 실행은 가져 오기로 간주되지 않으며 .pyc가 생성되지 않습니다.

예를 들어, 다른 모듈 xyz.py 를 가져 오는 abc.py 스크립트 파일이있는 경우 abc.py 를 실행하면 xyz를 가져 오기 때문에 xyz.pyc 가 작성되지만 abc 이후 에는 abc.pyc 파일이 작성 되지 않습니다 . py를 가져 오지 못했습니다.

가져 오지 않은 모듈에 대해 .pyc 파일을 작성해야하는 경우 py_compilecompileall모듈을 사용할 수 있습니다 .

py_compile모듈은 수동으로 모듈을 컴파일 할 수 있습니다. 한 가지 방법은 py_compile.compile해당 모듈 의 기능을 대화식 으로 사용하는 것입니다.

>>> import py_compile
>>> py_compile.compile('abc.py')

이것은 .pyc를 abc.py와 같은 위치에 씁니다 (선택적 매개 변수로이를 무시할 수 있습니다 cfile).

compileall 모듈을 사용하여 디렉토리의 모든 파일을 자동으로 컴파일 할 수도 있습니다.

python -m compileall

디렉토리 이름 (이 예에서 현재 디렉토리)이 생략되면, 모듈은 발견 된 모든 것을 컴파일합니다. sys.path


6
abc.py를 얻기 위해 컴파일하면 어떤 이점이 있습니까?
Saher Ahwal

@SaherAhwal 제가 생각할 수있는 한 가지 이점은 구문 검사입니다.
이 바오

20

파이썬 (적어도 가장 일반적인 구현)은 원본 소스를 바이트 코드로 컴파일 한 다음 가상 머신의 바이트 코드를 해석하는 패턴을 따릅니다. 이것은 (가장 일반적인 구현) 순수한 해석 기나 순수한 컴파일러가 아니라는 것을 의미합니다.

그러나 이것의 다른 측면은 컴파일 프로세스가 대부분 숨겨져 있다는 것입니다. .pyc 파일은 기본적으로 캐시처럼 취급됩니다. 속도가 빨라지지만 일반적으로 전혀 알 필요는 없습니다. 파일 시간 / 날짜 스탬프를 기반으로 필요할 때 자동으로 무효화하고 다시로드 (소스 코드를 다시 컴파일)합니다.

내가 이것에 대한 문제를 본 유일한 시간에 관해서는 컴파일 된 바이트 코드 파일이 어떻게 든 미래에 타임 스탬프를 얻었을 때, 항상 소스 파일보다 최신으로 보였습니다. 최신으로 보이므로 소스 파일은 다시 컴파일되지 않았으므로 변경 사항이 무엇이든간에 무시되었습니다 ...


12

파이썬의 * .py 파일은 코드를 작성하는 텍스트 파일입니다. "python filename.py"라고 말하여이 파일을 실행하려고하면

이 명령은 Python 가상 머신을 호출합니다. Python Virtual Machine에는 "컴파일러"와 "인터프리터"의 두 가지 구성 요소가 있습니다. 인터프리터는 * .py 파일의 텍스트를 직접 읽을 수 없으므로이 텍스트는 먼저 PVM (하드웨어가 아니라 PVM)을 대상으로하는 바이트 코드로 변환됩니다 . PVM은이 바이트 코드를 실행합니다. * .pyc 파일은 셸 또는 다른 파일의 파일에서 가져 오기 작업을 수행하는 파일을 실행하는 동안 생성됩니다.

이 * .pyc 파일이 이미 생성 된 경우 다음에 * .py 파일을 실행 / 실행할 때마다 시스템에서 직접 컴파일 할 필요가없는 * .pyc 파일을로드합니다 (이는 프로세서의 시스템 사이클을 절약합니다).

* .pyc 파일이 생성되면 편집하지 않는 한 * .py 파일이 필요하지 않습니다.


7

파이썬 코드는 2 단계로 진행됩니다. 첫 번째 단계는 코드를 실제로 바이트 코드 인 .pyc 파일로 컴파일합니다. 그런 다음이 .pyc 파일 (바이트 코드)은 CPython 인터프리터를 사용하여 해석됩니다. 링크를 참조하십시오 . 여기서 코드 컴파일 및 실행 프로세스는 쉬운 용어로 설명됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.