파이썬이 통역 된 언어라는 것을 이해하게되었습니다 ...
그러나 파이썬 소스 코드를 보면 .pyc
Windows가 "컴파일 된 파이썬 파일"로 식별되는 파일을 볼 수 있습니다.
이것들은 어디로 오나요?
java
and와 같이 분리하지 않고 하나의 실행 파일로 결합한다는 것 javac
입니다.
파이썬이 통역 된 언어라는 것을 이해하게되었습니다 ...
그러나 파이썬 소스 코드를 보면 .pyc
Windows가 "컴파일 된 파이썬 파일"로 식별되는 파일을 볼 수 있습니다.
이것들은 어디로 오나요?
java
and와 같이 분리하지 않고 하나의 실행 파일로 결합한다는 것 javac
입니다.
답변:
여기에는 바이트 코드가 포함되어 있는데, 이는 파이썬 인터프리터가 소스를 컴파일하는 것입니다. 이 코드는 파이썬의 가상 머신에 의해 실행됩니다.
파이썬의 문서는 다음과 같은 정의를 설명합니다 :
파이썬은 컴파일 된 언어와 달리 해석되는 언어이지만 바이트 코드 컴파일러의 존재로 인해 구별이 모호해질 수 있습니다. 즉, 실행 파일을 명시 적으로 작성하지 않고 소스 파일을 직접 실행할 수 있습니다.
파이썬은 통역 언어라는 것을 이해하게되었습니다 ...
이 대중적인 밈은 틀리거나 오히려 (자연적인) 언어 수준에 대한 오해에 기초하여 만들어졌습니다. 이와 비슷한 실수는 "성경은 두꺼운 표지의 책"이라고 말하는 것입니다. 그 직유를 설명하겠습니다 ...
"성경"은 책의 분류 (실제, 물리적 대상) 라는 의미에서 "책"입니다 . "성경의 사본들"로 식별 된 책들은 공통의 근본적인 내용을 가지고 있어야합니다 (내용은 비록 다른 언어로도 수용 될 수있는 번역, 각주 수준 및 주석이 다른 언어 일 수도 있지만). 기본적으로 고려 되지 않는 무수한 측면, 즉 바인딩의 종류, 바인딩의 색상, 인쇄에 사용 된 글꼴, 그림이있는 경우, 쓰기 가능한 여백이 있는지 여부, 숫자 및 내장 된 책갈피의 종류 등이 완전히 다릅니다. 등등.
성서 의 전형적인 인쇄는 실제로 하드 커버 제본 일 가능성이 높습니다. 결국이 책은 일반적으로 여러 곳에서 읽거나 여러 곳에서 책갈피를 지정하고 주어진 챕터 및 구절 포인터를 찾아서 표시하는 책입니다. 등을 사용하면 좋은 하드 커버 바인딩을 사용하면 해당 사본을 더 오래 사용할 수 있습니다. 그러나 이것들은 실제 책의 실제 사본이 성서의 사본인지 아닌지를 결정하는 데 사용할 수없는 일상적인 (실제적인) 문제입니다 : 페이퍼 백 인쇄가 완벽하게 가능합니다!
마찬가지로, 파이썬은 언어 구현 클래스를 정의한다는 의미에서 "언어"입니다. 언어 구현 클래스는 일부 기본 측면 (구문, 명시 적으로 다르게 허용되는 부분을 제외한 대부분의 의미론)에서 모두 유사해야하지만 완전히 허용됩니다. 제공된 소스 파일을 처리하는 방법, 소스를 일부 하위 레벨 형식으로 컴파일하는지 여부 (그러한 경우 어떤 형식)로 저장하는지 여부 등 모든 "구현"세부 사항이 거의 다름 컴파일 된 양식, 디스크 또는 다른 곳으로), 해당 양식을 실행하는 방법 등.
고전적인 구현 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 #은 일반적으로 오류를보다 철저하게 확인하고 더 많은 최적화를 수행하기 위해 컴파일 중에 더 많은 작업을 수용하므로 자동 컴파일을 수행하지 않습니다. 검은 색이나 흰색이 아닌 연속적인 그레이 스케일입니다.
통역 언어와 같은 것은 없습니다. 인터프리터 또는 컴파일러 사용 여부는 순전히 구현 의 특성입니다. 언어와는 전혀 관련이 없습니다.
마다 언어는 인터프리터 나 컴파일러로 구현할 수 있습니다. 대부분의 언어에는 각 유형마다 하나 이상의 구현이 있습니다. (예를 들어, C 및 C ++에 대한 인터프리터가 있으며 JavaScript, PHP, Perl, Python 및 Ruby에 대한 컴파일러가 있습니다.) 게다가 현대 언어 구현의 대부분은 실제로 인터프리터와 컴파일러 (또는 여러 컴파일러)를 결합합니다.
언어는 일련의 추상 수학 규칙입니다. 통역사는 언어에 대한 몇 가지 구체적인 구현 전략 중 하나입니다. 이 두 가지는 완전히 다른 추상화 수준에서 산다. 영어가 입력 언어 인 경우 "통역 언어"라는 용어는 유형 오류입니다. "Python은 해석 된 언어"라는 문장은 단지 거짓이 아닙니다 (거짓 인 경우에도 문장이 의미가 있음을 암시하기 때문에 의미가 없습니다) . 언어는 결코 다음과 같이 정의 될 수 없기 때문에 의미 가 없습니다. "해석"
특히 현재 존재하는 Python 구현을 살펴보면 다음과 같은 구현 전략이 사용됩니다.
해당 목록의 구현 중 하나 (그리고 tinypy, Shedskin 또는 Psyco와 같이 언급하지 않은 일부 구현)에는 컴파일러가 있음을 알 수 있습니다. 사실, 내가 아는 한, 현재 순수하게 해석 된 파이썬 구현은 없으며 그러한 구현도 계획되어 있지 않으며 그러한 구현은 없었습니다.
"해석 된 언어"라는 용어는 "해석 된 구현의 언어"를 의미하는 것으로 해석하더라도 이해가되지 않을뿐만 아니라 사실이 아닙니다. 당신에게 말한 사람은 분명히 그가 무슨 말을하는지 모릅니다.
특히, .pyc
보고있는 파일은 CPython, Stackless Python 또는 Unladen Swallow에 의해 생성 된 캐시 된 바이트 코드 파일입니다.
이것들은 .py
파일을 가져올 때 Python 인터프리터에 의해 생성되며 가져온 모듈 / 프로그램의 "컴파일 된 바이트 코드"를 포함합니다. 소스 코드에서 바이트 코드로의 "번역"(한 번만 수행하면 됨) 파일 이 해당 파일 보다 최신 import
이면 후속 s 에서 건너 뛸 수 있으므로 시작 속도가 약간 빨라집니다. 그러나 여전히 해석됩니다..pyc
.py
모듈 로딩 속도를 높이기 위해 Python은 컴파일 된 모듈 내용을 .pyc에 캐시합니다.
CPython은 소스 코드를 "바이트 코드"로 컴파일하고 성능상의 이유로 소스 파일이 변경 될 때마다 파일 시스템에이 바이트 코드를 캐시합니다. 컴파일 단계를 무시할 수 있기 때문에 파이썬 모듈의 로딩이 훨씬 빨라집니다. 소스 파일이 foo.py 인 경우 CPython은 소스 바로 옆의 foo.pyc 파일에 바이트 코드를 캐시합니다.
python3에서 Python의 가져 오기 메커니즘은 모든 Python 패키지 디렉토리 내의 단일 디렉토리에서 바이트 코드 캐시 파일을 작성하고 검색하도록 확장되었습니다. 이 디렉토리는 __pycache__라고합니다.
모듈로드 방법을 설명하는 순서도는 다음과 같습니다.
자세한 내용은:
참조 : PEP3147
참조 : "컴파일 된"Python 파일
이것은 초보자를위한 것입니다.
파이썬은 스크립트를 컴파일하기 전에 바이트 코드라고하는 컴파일 된 코드로 자동 컴파일합니다.
스크립트 실행은 가져 오기로 간주되지 않으며 .pyc가 생성되지 않습니다.
예를 들어, 다른 모듈 xyz.py 를 가져 오는 abc.py 스크립트 파일이있는 경우 abc.py 를 실행하면 xyz를 가져 오기 때문에 xyz.pyc 가 작성되지만 abc 이후 에는 abc.pyc 파일이 작성 되지 않습니다 . py를 가져 오지 못했습니다.
가져 오지 않은 모듈에 대해 .pyc 파일을 작성해야하는 경우 py_compile
및 compileall
모듈을 사용할 수 있습니다 .
py_compile
모듈은 수동으로 모듈을 컴파일 할 수 있습니다. 한 가지 방법은 py_compile.compile
해당 모듈 의 기능을 대화식 으로 사용하는 것입니다.
>>> import py_compile
>>> py_compile.compile('abc.py')
이것은 .pyc를 abc.py와 같은 위치에 씁니다 (선택적 매개 변수로이를 무시할 수 있습니다 cfile
).
compileall 모듈을 사용하여 디렉토리의 모든 파일을 자동으로 컴파일 할 수도 있습니다.
python -m compileall
디렉토리 이름 (이 예에서 현재 디렉토리)이 생략되면, 모듈은 발견 된 모든 것을 컴파일합니다. sys.path
파이썬 (적어도 가장 일반적인 구현)은 원본 소스를 바이트 코드로 컴파일 한 다음 가상 머신의 바이트 코드를 해석하는 패턴을 따릅니다. 이것은 (가장 일반적인 구현) 순수한 해석 기나 순수한 컴파일러가 아니라는 것을 의미합니다.
그러나 이것의 다른 측면은 컴파일 프로세스가 대부분 숨겨져 있다는 것입니다. .pyc 파일은 기본적으로 캐시처럼 취급됩니다. 속도가 빨라지지만 일반적으로 전혀 알 필요는 없습니다. 파일 시간 / 날짜 스탬프를 기반으로 필요할 때 자동으로 무효화하고 다시로드 (소스 코드를 다시 컴파일)합니다.
내가 이것에 대한 문제를 본 유일한 시간에 관해서는 컴파일 된 바이트 코드 파일이 어떻게 든 미래에 타임 스탬프를 얻었을 때, 항상 소스 파일보다 최신으로 보였습니다. 최신으로 보이므로 소스 파일은 다시 컴파일되지 않았으므로 변경 사항이 무엇이든간에 무시되었습니다 ...
파이썬의 * .py 파일은 코드를 작성하는 텍스트 파일입니다. "python filename.py"라고 말하여이 파일을 실행하려고하면
이 명령은 Python 가상 머신을 호출합니다. Python Virtual Machine에는 "컴파일러"와 "인터프리터"의 두 가지 구성 요소가 있습니다. 인터프리터는 * .py 파일의 텍스트를 직접 읽을 수 없으므로이 텍스트는 먼저 PVM (하드웨어가 아니라 PVM)을 대상으로하는 바이트 코드로 변환됩니다 . PVM은이 바이트 코드를 실행합니다. * .pyc 파일은 셸 또는 다른 파일의 파일에서 가져 오기 작업을 수행하는 파일을 실행하는 동안 생성됩니다.
이 * .pyc 파일이 이미 생성 된 경우 다음에 * .py 파일을 실행 / 실행할 때마다 시스템에서 직접 컴파일 할 필요가없는 * .pyc 파일을로드합니다 (이는 프로세서의 시스템 사이클을 절약합니다).
* .pyc 파일이 생성되면 편집하지 않는 한 * .py 파일이 필요하지 않습니다.