.pyc 파일은 언제 새로 고침 되나요?


91

".pyc"파일은 일반 텍스트 ".py"파일의 컴파일 된 버전으로, 프로그램을 더 빠르게 실행하기 위해 런타임에 생성된다는 것을 알고 있습니다. 그러나 나는 몇 가지를 관찰했습니다.

  1. "py"파일을 수정하면 프로그램 동작이 변경됩니다. 이것은 "py"파일이 컴파일되거나 적어도 일종의 해싱 프로세스를 거치거나 다시 컴파일해야하는지 여부를 알려주기 위해 타임 스탬프를 비교한다는 것을 나타냅니다.
  2. 모든 ".pyc"파일 ( rm *.pyc) 을 삭제하면 프로그램 동작이 변경되는 경우가 있습니다. 이는 ".py"업데이트시 컴파일되지 않음을 나타냅니다.

질문 :

  • 언제 컴파일할지 어떻게 결정합니까?
  • 개발 중에 더 엄격한 검사를 할 수있는 방법이 있습니까?

14
.pyc 파일을 rm *.pyc. 중첩 폴더의 .pyc 파일은 삭제되지 않습니다. 사용 find . -name '*.pyc' -delete대신에
저쪽으로 네요

6
아마도 귀하의 질문에 대한 한 가지 메모 : '.py'파일에서 읽을 때보 다 '.pyc'또는 '.pyo'파일에서 읽을 때 프로그램이 더 빨리 실행되지 않습니다. '.pyc'또는 '.pyo'파일에 대해 더 빠른 유일한 것은 파일이로드되는 속도입니다. 링크
매기

@maggie 로딩과 실행 시간의 차이점은 무엇입니까?
Daniel Springer

3
@Dani 로딩은 프로그램을 읽고 컴파일하는 데 걸리는 시간입니다. 실행 시간은 프로그램이 실제로 실행되는 시간이며로드 후 발생합니다. 기술적으로 원하는 경우 시간 유형은로드 시간, 컴파일 시간, 링크 시간 및 실행 시간입니다. .pyc를 만들면 컴파일 시간 부분이 제거됩니다.
Eric Klien

@EricKlien 덕분에 남자
다니엘 스프링

답변:


79

.pyc파일은 파이썬 파일을 다른 스크립트에서 가져올 경우에만 생성 (및 덮어 쓰기)된다. 가져 오기가 호출되면 Python은 .pyc파일의 내부 타임 스탬프가 해당 .py파일 보다 오래되지 않았 는지 확인 합니다. 그럴 경우 .pyc; .pyc존재하지 않거나 아직 존재하지 않는 경우 Python은 .py파일을 a로 컴파일 .pyc하고로드합니다.

"엄격한 검사"란 무엇을 의미합니까?


3
에서 문제를 해결할 수 있습니다 rm *.pyc. 모든 파일을 강제로 다시 생성하면 파일이 자체적으로 다시 컴파일되지 않음을 나타내는 일부 문제가 해결된다는 것을 알고 있습니다. 타임 스탬프를 사용하면이 동작을 더 엄격하게 만들 방법이 없다고 생각하지만 문제는 여전히 지속됩니다.
Aaron Schif 2013

13
이것은 정확하지 않습니다. 타임 스탬프는 일치 할 필요가 없으며 일반적으로 일치하지 않습니다. .pyc의 타임 스탬프가 있어야합니다 나이가 대응하는 것보다 .py재 컴파일을 트리거의 타임 스탬프 '.
Tim Pietzcker 2013

4
@Aaron, .py 파일을 변경하는 중일 수 있으며, 그 과정에서 이전 파일을 만들고 있습니까 (예 : '수정 시간'을 보존하는 작업을 사용하여 다른 디렉토리에서 복사)?
greggo 2013

1
@greggo, 나는 git을 사용하고 저장소에서 업데이트하고 있으므로 나는 그렇습니다. 그렇게 할 수 있습니다. 감사.
Aaron Schif 2013

1
알아 둘만 한. 그럼 당신의 대답을 고치는 것은 어떻습니까?
Piotr Dobrogost

29

.pyc 파일은 해당 코드 요소를 가져올 때마다 생성되며 해당 코드 파일이 업데이트 된 경우 업데이트됩니다. .pyc 파일이 삭제되면 자동으로 다시 생성됩니다. 그러나 해당 코드 파일이 삭제 될 때 자동으로 삭제 되지않습니다 .

이로 인해 파일 수준 리팩터링 중에 정말 재미있는 버그가 발생할 수 있습니다.

우선, 자신의 컴퓨터에서만 작동하고 다른 사람에게는 작동하지 않는 코드를 푸시 할 수 있습니다. 삭제 한 파일에 대한 댕글 링 참조가있는 경우 .pyc 파일을 가져 오기에 사용할 수 있으므로 관련 .pyc 파일을 수동으로 삭제하지 않으면 로컬에서 계속 작동합니다. 이것은 적절하게 구성된 버전 제어 시스템이 .py 파일이 아닌 중앙 저장소로만 .py 파일을 푸시한다는 사실과 더해집니다. 즉, 코드가 "가져 오기 테스트"(모든 것을 가져 오면 괜찮음)를 통과 할 수 있습니다. 다른 사람의 컴퓨터에서 작업합니다.

둘째, 패키지를 모듈로 바꾸면 꽤 끔찍한 버그가 생길 수 있습니다. 패키지 ( __init__.py파일이 있는 폴더 )를 모듈 (.py 파일)로 변환하면 한 때 해당 패키지를 나타내는 .pyc 파일이 남아 있습니다. 특히 __init__.pyc유적. 따라서 중요하지 않은 코드가 포함 된 foo 패키지가있는 경우 나중에 해당 패키지를 삭제하고 일부 기능이있는 foo.py 파일을 만들고 다음 def bar(): pass을 실행합니다.

from foo import bar

당신은 얻는다 :

ImportError: cannot import name bar

파이썬은 여전히 ​​foo 패키지의 이전 .pyc 파일을 사용하고 있기 때문에 어느 것도 bar를 정의하지 않습니다. 이것은 .pyc 파일로 인해 완전히 작동하는 코드가 손상 될 수있는 웹 서버에서 특히 문제가 될 수 있습니다.

이러한 두 가지 이유 (및 다른 이유)의 결과로 배포 코드와 테스트 코드는 다음과 같은 bash 행과 같이 .pyc 파일을 삭제해야합니다.

find . -name '*.pyc' -delete

또한 python 2.6부터 -B.pyc 파일을 사용하지 않도록 플래그 와 함께 python을 실행할 수 있습니다. .pyc 파일을 피하는 방법을 참조하십시오 . 상세 사항은.

참고 항목 : 프로젝트에서 모든 .pyc 파일을 제거하려면 어떻게합니까?


"모듈 ( __init__.py파일이 있는 폴더)을 변환 할 때 ...". 그것은 모듈이 아니라 패키지 일 것입니다.
로버트 데이비드 그랜트

2
특히 __init__.pyc유적. -왜? 패키지는 패키지 수단 삭제 디렉토리를 삭제하는 디렉토리이기 때문에 ... 어떤 파일이 남아 있지있다
표트르 Dobrogost

3
@PiotrDobrogost 적절하게 관리되는 소스 제어에는 pyc 파일을 소스로 검사하지 않는 것이 포함됩니다. 따라서 로컬 복사본에서 pyc 파일을 포함한 폴더를 삭제할 수 있지만 git pull을 수행하는 다른 사람에 대해서는 삭제되지 않습니다. 배포에 git pull이 포함 된 경우 서버가 중단 될 수 있습니다.
Zags

개발 환경이 코드가 배포 될 위치를 대표한다고 믿지 않는 데는 여러 가지 이유가 있습니다. 이 .pyc문제는 OS 및 유틸리티 패치 수준, .so파일, 구성 파일, 기타 Python libs (가상 환경에서 실행되지 않는 경우) 에 대한 숨겨진 종속성 , 모호한 env vars ... 목록이 계속됩니다. 철저하게 이러한 문제를 모두 찾으려면 git 리포지토리에서 코드의 깨끗한 복사본을 만들거나 PyPi 스타일 서버에 패키지로 게시하고 새로운 VM에서 전체 복제 또는 설정을 수행해야합니다. 이러한 잠재적 인 문제 중 일부는 .pyc비교 에서이 문제를 창백 하게 만듭니다 .
크리스 존슨
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.