zipfile — ZIP 아카이브 다루기

zipfile — ZIP 아카이브 다루기

ZIP 파일 형식은 흔한 압축 아카이브 표준이에요. zipfile 모듈은 ZIP 파일을 만들고, 읽고, 쓰고, 이어 붙이고, 목록화하는 도구를 제공합니다. 이 모듈을 고급으로 쓰려면 PKZIP Application Note에 정의된 형식에 대한 이해가 필요해요.

출처: Python 표준 라이브러리

본문

ZIP 파일 형식은 흔한 아카이브·압축 표준입니다. 이 모듈은 ZIP 파일을 만들고, 읽고, 쓰고, 이어 붙이고, 목록화하는 도구를 제공해요. 이 모듈을 고급으로 사용하려면 PKZIP Application Note에 정의된 형식에 대한 이해가 필요합니다.

이 모듈은 멀티파트 ZIP 파일은 처리하지 않아요. ZIP64 확장을 쓰는 ZIP 파일(즉 4GiB보다 큰 ZIP 파일)은 처리할 수 있습니다. ZIP 아카이브의 암호화된 파일 복호화는 지원하지만, 암호화된 파일을 만들 수는 없어요. 복호화는 C가 아닌 네이티브 Python으로 구현되어 매우 느립니다.

압축된 아카이브 처리는 zlib, bz2, lzma, compression.zstd 같은 선택 모듈이 필요합니다. 그것들 중 하나라도 CPython 배포판에서 빠져 있다면 배포자의 문서를 찾아보세요.

이 모듈은 다음 항목을 정의합니다.

  • exception zipfile.BadZipFile — 잘못된 ZIP 파일에 대해 발생하는 오류. (버전 3.2에서 추가)
  • exception zipfile.BadZipfile — 이전 Python 버전과의 호환을 위한 BadZipFile의 별칭. (버전 3.2부터 비추천)
  • exception zipfile.LargeZipFile — ZIP 파일에 ZIP64 기능이 필요하지만 활성화되지 않았을 때 발생하는 오류.
  • class zipfile.ZipFile — ZIP 파일을 읽고 쓰는 클래스. 생성자 세부 사항은 ZipFile objects 절 참고.
  • class zipfile.Pathpathlib.Path가 제공하는 인터페이스의 부분집합을 구현하는 클래스로, 전체 importlib.resources.abc.Traversable 인터페이스를 포함합니다. (버전 3.8에서 추가)
  • class zipfile.PyZipFile — Python 라이브러리를 담는 ZIP 아카이브를 만드는 클래스.

class zipfile.ZipInfo(filename='NoName', date_time=(1980, 1, 1, 0, 0, 0))

아카이브 멤버에 대한 정보를 나타내는 데 쓰는 클래스입니다. 이 클래스의 인스턴스는 ZipFile 객체의 getinfo()infolist() 메서드가 반환해요. zipfile 모듈의 대부분 사용자는 이들을 만들 필요 없이 모듈이 만든 것만 사용합니다. filename은 아카이브 멤버의 전체 이름이어야 하고, date_time은 파일의 마지막 수정 시간을 설명하는 여섯 필드의 튜플이어야 합니다. 필드는 ZipInfo objects 절에 설명되어 있어요.

버전 3.13에서 변경: 이전에 보호된 _compresslevel을 노출하는 공개 compress_level 속성이 추가되었습니다. 옛 보호 이름은 하위 호환을 위해 프로퍼티로 계속 동작합니다.

_for_archive(archive)

date_time, 압축 속성, 외부 속성을 ZipFile.writestr()이 쓰는 적절한 기본값으로 해석합니다. 체이닝을 위해 self를 반환합니다. (버전 3.14에서 추가)

zipfile.is_zipfile(filename)

매직 넘버를 기준으로 filename이 유효한 ZIP 파일이면 True, 아니면 False를 반환합니다. filename은 파일 또는 파일류 객체일 수 있어요. (버전 3.1에서 변경: 파일·파일류 객체 지원)

zipfile.ZIP_STORED

압축되지 않은 아카이브 멤버에 대한 숫자 상수입니다.

zipfile.ZIP_DEFLATED

보통 ZIP 압축 방법에 대한 숫자 상수. zlib 모듈이 필요합니다.

zipfile.ZIP_BZIP2

BZIP2 압축 방법에 대한 숫자 상수. bz2 모듈이 필요합니다. (버전 3.3에서 추가)

zipfile.ZIP_LZMA

LZMA 압축 방법에 대한 숫자 상수. lzma 모듈이 필요합니다. (버전 3.3에서 추가)

zipfile.ZIP_ZSTANDARD

Zstandard 압축에 대한 숫자 상수. compression.zstd 모듈이 필요합니다. (버전 3.14에서 추가)

참고 — APPNOTE 6.3.7에서는 Zstandard 압축에 메서드 ID 20이 할당되었습니다. 이는 충돌을 피하기 위해 APPNOTE 6.3.8에서 메서드 ID 93으로 바뀌었고 메서드 ID 20은 비추천되었어요. 호환성을 위해 zipfile 모듈은 두 메서드 ID를 모두 읽지만 데이터는 메서드 ID 93으로만 씁니다.

참고 — ZIP 파일 형식 명세는 bzip2 압축(2001년), LZMA 압축(2006년), Zstandard 압축(2020년)을 오래전부터 지원해 왔습니다. 그러나 일부 도구(구형 Python 릴리스 포함)는 이 압축 방법을 지원하지 않아 ZIP 파일 전체를 처리하지 않거나 개별 파일 추출에 실패할 수 있습니다.

관련 자료 — PKZIP Application Note(Phil Katz가 만든 ZIP 파일 형식 문서), Info-ZIP Home Page(Info-ZIP 프로젝트의 ZIP 아카이브 프로그램·개발 라이브러리 정보).

ZipFile 객체

class zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True, metadata_encoding=None)

ZIP 파일을 엽니다. file은 파일 경로(문자열), 파일류 객체 또는 path류 객체일 수 있어요.

mode 매개변수는 기존 파일을 읽으려면 'r', 새 파일을 자르고 쓰려면 'w', 기존 파일에 이어 붙이려면 'a', 새 파일을 독점적으로 만들어 쓰려면 'x'여야 해요. mode'x'이고 file이 기존 파일을 가리키면 FileExistsError가 발생합니다. mode'a'이고 file이 기존 ZIP 파일을 가리키면 추가 파일이 거기에 더해지며, file이 ZIP 파일을 가리키지 않으면 파일에 새 ZIP 아카이브가 이어 붙여져요. 이는 ZIP 아카이브를 다른 파일(예: python.exe)에 추가하기 위한 것입니다. mode'a'이고 파일이 전혀 존재하지 않으면 만들어집니다. mode'r' 또는 'a'이면 파일은 탐색 가능해야 해요.

compression은 아카이브를 쓸 때 사용할 ZIP 압축 방법으로, ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2, ZIP_LZMA, ZIP_ZSTANDARD 중 하나여야 합니다. 인식되지 않는 값은 NotImplementedError를 일으켜요. ZIP_DEFLATED, ZIP_BZIP2, ZIP_LZMA, ZIP_ZSTANDARD를 지정했는데 해당 모듈(zlib, bz2, lzma, compression.zstd)을 사용할 수 없으면 RuntimeError가 발생합니다. 기본은 ZIP_STORED예요.

allowZip64True(기본)이면 zipfile이 4GiB보다 클 때 ZIP64 확장을 쓰는 ZIP 파일을 만들어요. 거짓이면 ZIP 파일이 ZIP64 확장을 요구할 때 zipfile이 예외를 일으킵니다.

compresslevel 매개변수는 아카이브에 파일을 쓸 때 사용할 압축 수준을 제어합니다. ZIP_STOREDZIP_LZMA를 쓸 때는 효과가 없어요. ZIP_DEFLATED를 쓸 때는 09 정수를 받고(zlib 참고), ZIP_BZIP2를 쓸 때는 19 정수를 받으며(bz2 참고), ZIP_ZSTANDARD를 쓸 때는 -131072~22 정수를 보통 받습니다(유효한 값과 그 의미는 CompressionParameter.compression_level 참고).

strict_timestamps 인자를 False로 설정하면 1980-01-01보다 오래된 파일을 타임스탬프를 1980-01-01로 설정하는 대가로 압축할 수 있어요. 2107-12-31보다 새로운 파일에서도 비슷한 동작이 일어나며 타임스탬프가 한계로 설정됩니다.

mode'r'일 때 metadata_encoding을 코덱 이름으로 설정할 수 있는데, 멤버 이름과 ZIP 주석 같은 메타데이터를 디코드하는 데 사용됩니다.

파일이 'w', 'x', 'a' 모드로 만들어지고 아카이브에 어떤 파일도 추가하지 않고 닫히면, 빈 아카이브에 적절한 ZIP 구조가 파일에 기록됩니다.

ZipFile은 컨텍스트 관리자이기도 해서 with 문을 지원합니다. 예제에서 myzipwith 문의 본문이 끝난 뒤 닫혀요 — 예외가 발생해도 마찬가지입니다.

with ZipFile('spam.zip', 'w') as myzip:
    myzip.write('eggs.txt')

참고metadata_encodingZipFile의 인스턴스 전반 설정입니다. 멤버별로 설정할 수 없어요. 이 속성은 현재 로케일 인코딩이나 코드 페이지(주로 Windows)의 이름으로 아카이브를 만드는 레거시 구현을 위한 해결책입니다. .ZIP 표준에 따르면 메타데이터의 인코딩은 아카이브 헤더의 플래그로 IBM 코드 페이지(기본) 또는 UTF-8로 지정될 수 있어요. 그 플래그가 Python 특정 확장인 metadata_encoding보다 우선합니다.

버전 3.2에서 변경: ZipFile을 컨텍스트 관리자로 쓰는 능력 추가. 버전 3.3에서 변경: bzip2와 lzma 압축 지원 추가. 버전 3.4에서 변경: ZIP64 확장이 기본적으로 활성화됨. 버전 3.5에서 변경: 탐색 불가능한 스트림에 쓰기 지원, 'x' 모드 지원 추가. 버전 3.6에서 변경: 이전에는 인식되지 않는 압축 값에 대해 단순 RuntimeError가 발생했습니다. 버전 3.6.2에서 변경: file 매개변수가 path류 객체를 받습니다. 버전 3.7에서 변경: compresslevel 매개변수 추가. 버전 3.8에서 변경: 키워드 전용 strict_timestamps 매개변수. 버전 3.11에서 변경: zipfile의 디렉터리·파일 헤더에서 메타데이터를 읽을 때 멤버 이름 인코딩 지정 지원 추가.

ZipFile.close()

아카이브 파일을 닫습니다. 프로그램을 종료하기 전에 close()를 호출해야 합니다. 그렇지 않으면 필수 기록이 쓰이지 않아요.

ZipFile.getinfo(name)

아카이브 멤버 name에 대한 정보를 담은 ZipInfo 객체를 반환합니다. 아카이브에 현재 포함되지 않은 이름에 대해 getinfo()를 호출하면 KeyError가 발생합니다.

ZipFile.infolist()

아카이브의 각 멤버에 대한 ZipInfo 객체를 담은 목록을 반환합니다. 기존 아카이브를 열었다면 객체는 디스크의 실제 ZIP 파일에 있는 항목과 같은 순서입니다.

ZipFile.namelist()

아카이브 멤버를 이름으로 목록화해 반환합니다.

ZipFile.open(name, mode='r', pwd=None, *, force_zip64=False)

아카이브 멤버에 바이너리 파일류 객체로 접근합니다. name은 아카이브 안의 파일 이름 또는 ZipInfo 객체일 수 있어요. 포함하면 mode 매개변수는 'r'(기본) 또는 'w'여야 합니다. pwd는 암호화된 ZIP 파일을 복호화하는 데 쓰는 bytes 객체의 비밀번호입니다.

open()은 컨텍스트 관리자이기도 해서 with 문을 지원합니다.

with ZipFile('spam.zip') as myzip:
    with myzip.open('eggs.txt') as myfile:
        print(myfile.read())

'r' 모드에서 파일류 객체(ZipExtFile)는 읽기 전용이며 read(), readline(), readlines(), seek(), tell(), __iter__(), __next__() 메서드를 제공합니다. 이 객체들은 ZipFile과 독립적으로 동작할 수 있어요.

mode='w'로는 쓰기 가능한 파일 핸들이 반환되며 write() 메서드를 지원합니다. 쓰기 가능한 파일 핸들이 열려 있는 동안 ZIP 파일의 다른 파일들을 읽거나 쓰려 하면 ValueError가 발생합니다.

두 경우 모두 파일류 객체는 name(아카이브 안의 파일 이름과 동등)과 mode(입력 모드에 따라 'rb' 또는 'wb') 속성도 가져요. 파일을 쓸 때 파일 크기를 미리 모르지만 2GiB를 넘을 수 있다면, force_zip64=True를 넘겨 헤더 형식이 큰 파일을 지원할 수 있게 하세요. 파일 크기를 미리 알면 file_size가 설정된 ZipInfo 객체를 만들어 그걸 name 매개변수로 쓰면 됩니다.

참고open(), read(), extract() 메서드는 파일 이름 또는 ZipInfo 객체를 받을 수 있어요. 중복 이름을 가진 멤버를 포함하는 ZIP 파일을 읽을 때 유용하다는 걸 알게 될 거예요.

버전 3.6에서 변경: mode='U' 지원 제거. 범용 개행 모드로 압축 텍스트 파일을 읽으려면 io.TextIOWrapper를 사용하세요. 버전 3.6에서 변경: ZipFile.open()mode='w' 옵션으로 아카이브에 파일을 쓰는 데 쓸 수 있게 됨. 버전 3.6에서 변경: 닫힌 ZipFile에서 open() 호출은 ValueError를 일으킵니다. 이전엔 RuntimeError였습니다. 버전 3.13에서 변경: 쓰기 가능한 파일류 객체에 name·mode 속성 추가. 읽기 가능한 파일류 객체의 mode 속성 값이 'r'에서 'rb'로 바뀌었습니다.

ZipFile.extract(member, path=None, pwd=None)

아카이브에서 현재 작업 디렉터리로 멤버를 추출합니다. member는 전체 이름 또는 ZipInfo 객체여야 해요. 파일 정보는 가능한 한 정확하게 추출됩니다. path는 추출할 다른 디렉터리를 지정합니다. member는 파일 이름 또는 ZipInfo 객체일 수 있습니다. pwd는 암호화된 파일에 쓰는 비밀번호(bytes 객체)예요. 만들어진 정규화된 경로(디렉터리 또는 새 파일)를 반환합니다.

참고 — 멤버 파일 이름이 절대 경로이면 드라이브/UNC 공유 지점과 앞의 (역)슬래시가 제거됩니다. 예: Unix에서 ///foo/barfoo/bar로, Windows에서 C:\foo\barfoo\bar가 됩니다. 그리고 멤버 파일 이름의 모든 ".." 구성 요소가 제거됩니다. 예: ../../foo../../ba..rfoo../ba..r이 됩니다. Windows에서 불법 문자(:, <, >, |, ", ?, *)는 밑줄(_)로 바뀝니다.

버전 3.6에서 변경: 닫힌 ZipFile에서 extract() 호출은 ValueError, 이전엔 RuntimeError. 버전 3.6.2에서 변경: path 매개변수가 path류 객체를 받습니다.

ZipFile.extractall(path=None, members=None, pwd=None)

아카이브의 모든 멤버를 현재 작업 디렉터리로 추출합니다. path는 추출할 다른 디렉터리를, members는 선택 사항으로 namelist()가 반환한 목록의 부분집합이어야 하며, pwd는 암호화된 파일에 쓰는 비밀번호(bytes 객체)예요.

경고 — 사전 검사 없이 신뢰할 수 없는 소스의 아카이브를 절대 추출하지 마세요. 절대 파일 이름이나 ".." 구성 요소를 가진 멤버처럼 path 밖에 파일이 만들어질 수 있습니다. 이 모듈은 그것을 막으려 시도해요. extract() 참고.

버전 3.6에서 변경: 닫힌 ZipFile에서 extractall() 호출은 ValueError, 이전엔 RuntimeError. 버전 3.6.2에서 변경: path 매개변수가 path류 객체를 받습니다.

ZipFile.printdir()

아카이브의 목차를 sys.stdout에 출력합니다.

ZipFile.setpassword(pwd)

암호화된 파일을 추출할 기본 비밀번호로 pwd(bytes 객체)를 설정합니다.

ZipFile.read(name, pwd=None)

아카이브에 있는 파일 name의 바이트를 반환합니다. name은 아카이브 안의 파일 이름 또는 ZipInfo 객체이에요. 아카이브는 읽기 또는 추가용으로 열려 있어야 합니다. pwd는 암호화된 파일에 쓰는 비밀번호(bytes 객체)이며, 지정하면 setpassword()로 설정한 기본 비밀번호를 오버라이드합니다. ZIP_STORED, ZIP_DEFLATED, ZIP_BZIP2, ZIP_LZMA, ZIP_ZSTANDARD가 아닌 압축 방법을 쓰는 ZipFile에서 read()를 호출하면 NotImplementedError가 발생해요. 해당 압축 모듈이 없어도 오류가 발생합니다.

버전 3.6에서 변경: 닫힌 ZipFile에서 read() 호출은 ValueError, 이전엔 RuntimeError.

ZipFile.testzip()

아카이브의 모든 파일을 읽고 CRC와 파일 헤더를 검사합니다. 첫 번째 불량 파일의 이름을 반환하거나, 아니면 None을 반환합니다.

버전 3.6에서 변경: 닫힌 ZipFile에서 testzip() 호출은 ValueError, 이전엔 RuntimeError.

ZipFile.write(filename, arcname=None, compress_type=None, compresslevel=None)

filename이라는 파일을 아카이브에 쓰고 아카이브 이름 arcname을 부여합니다 (기본적으로 filename과 같지만 드라이브 문자 없이 앞의 경로 구분자가 제거됨). compress_type이 주어지면 새 항목의 생성자 compression 매개변수 값을 오버라이드합니다. 마찬가지로 compresslevel도 주어지면 생성자를 오버라이드합니다. 아카이브는 'w', 'x', 'a' 모드로 열려 있어야 해요.

참고 — ZIP 파일 표준은 역사적으로 메타데이터 인코딩을 지정하지 않았지만 상호 운용을 위해 CP437(원래 IBM PC 인코딩)을 강력히 권장했습니다. 최근 버전은 (유일하게) UTF-8 사용을 허용합니다. 이 모듈에서 멤버 이름에 비-ASCII 문자가 포함되면 UTF-8이 자동으로 쓰여요. 멤버 이름을 ASCII 또는 UTF-8이 아닌 다른 인코딩으로 쓸 수는 없습니다. 참고 — 아카이브 이름은 아카이브 루트 기준이어야 하며, 즉 경로 구분자로 시작하면 안 됩니다. 참고arcname(또는 arcname이 주어지지 않으면 filename)에 null 바이트가 포함되면 아카이브의 파일 이름이 null 바이트에서 잘립니다. 참고 — 파일 이름의 앞 슬래시는 Windows 시스템의 일부 zip 프로그램에서 아카이브를 열 수 없게 만들 수 있습니다.

버전 3.6에서 변경: 'r' 모드로 만들었거나 닫힌 ZipFile에서 write() 호출은 ValueError, 이전엔 RuntimeError.

ZipFile.writestr(zinfo_or_arcname, data, compress_type=None, compresslevel=None)

파일을 아카이브에 씁니다. 내용은 datastr 또는 bytes 인스턴스일 수 있으며, str이면 먼저 UTF-8로 인코딩됩니다. zinfo_or_arcname은 아카이브에서 부여될 파일 이름 또는 ZipInfo 인스턴스예요. 인스턴스라면 적어도 파일 이름, 날짜, 시간이 주어져야 합니다. 이름이라면 날짜와 시간이 현재 날짜와 시간으로 설정됩니다. 아카이브는 'w', 'x', 'a' 모드로 열려 있어야 합니다. compress_type이 주어지면 새 항목의 생성자 compression 매개변수(또는 ZipInfo 인스턴스라면 zinfo_or_arcname) 값을 오버라이드해요. 마찬가지로 compresslevel도 주어지면 생성자를 오버라이드합니다.

참고zinfo_or_arcname 매개변수로 ZipInfo 인스턴스를 넘기면 사용되는 압축 방법은 주어진 ZipInfo 인스턴스의 compress_type 멤버에 지정된 것입니다. 기본적으로 ZipInfo 생성자는 이 멤버를 ZIP_STORED로 설정합니다.

버전 3.2에서 변경: compress_type 인자. 버전 3.6에서 변경: 'r' 모드로 만들었거나 닫힌 ZipFile에서 writestr() 호출은 ValueError, 이전엔 RuntimeError. 버전 3.14에서 변경: 이제 SOURCE_DATE_EPOCH 환경 변수를 존중합니다. 설정되어 있으면 현재 시간 대신 이 값을 ZIP 아카이브에 쓴 파일의 수정 타임스탬프로 사용합니다.

ZipFile.mkdir(zinfo_or_directory, mode=511)

아카이브 안에 디렉터리를 만듭니다. zinfo_or_directory가 문자열이면 mode 인자에 지정된 모드로 아카이브 안에 디렉터리가 만들어집니다. 그러나 zinfo_or_directoryZipInfo 인스턴스라면 mode 인자는 무시됩니다. 아카이브는 'w', 'x', 'a' 모드로 열려 있어야 해요. (버전 3.11에서 추가)

다음 데이터 속성도 사용할 수 있습니다.

  • ZipFile.filename — ZIP 파일의 이름.
  • ZipFile.debug — 사용할 디버그 출력 수준. 0(기본, 출력 없음)에서 3(가장 많은 출력)까지 설정할 수 있어요. 디버깅 정보는 sys.stdout에 기록됩니다.
  • ZipFile.comment — ZIP 파일과 연결된 bytes 객체의 주석. 'w', 'x', 'a' 모드로 만든 ZipFile 인스턴스에 주석을 할당하면 65535바이트보다 길면 안 됩니다. 이보다 긴 주석은 잘려요.

Path 객체

class zipfile.Path(root, at='')

루트 zipfile(이것은 ZipFile 인스턴스이거나 ZipFile 생성자에 넘기기 적합한 파일일 수 있음)에서 Path 객체를 만듭니다. at은 zipfile 안에서 이 Path의 위치를 지정합니다. 예: 'dir/file.txt', 'dir/', ''. 기본값은 루트를 나타내는 빈 문자열입니다.

참고Path 클래스는 ZIP 아카이브 안의 파일 이름을 정화(sanitize)하지 않습니다. ZipFile.extract()·ZipFile.extractall() 메서드와 달리, 경로 순회 취약점(예: 절대 경로나 ".." 구성 요소)을 막으려면 파일 이름을 검증하거나 정화하는 것은 호출자의 책임이에요. 신뢰할 수 없는 아카이브를 다룰 때는 os.path.abspath()로 파일 이름을 해석하고 os.path.commonpath()로 대상 디렉터리와 대조하는 것을 고려하세요.

Path 객체는 pathlib.Path 객체의 다음 기능을 노출합니다.

  • Path 객체는 / 연산자나 joinpath로 순회할 수 있습니다.
  • Path.name — 마지막 경로 구성 요소.
  • Path.open(mode='r', *, pwd, **) — 현재 경로에서 ZipFile.open()을 호출합니다. 지원되는 모드('r', 'w', 'rb', 'wb')를 통해 읽기·쓰기, 텍스트·바이너리로 열 수 있습니다. 위치·키워드 인자는 텍스트로 열 때 io.TextIOWrapper에 전달되고 그 외에는 무시됩니다. pwdZipFile.open()pwd 매개변수입니다. (버전 3.9에서 변경: open의 텍스트·바이너리 모드 지원 추가, 기본 모드는 이제 텍스트 / 버전 3.11.2에서 변경: encoding 매개변수를 TypeError 없이 위치 인자로 제공 가능)
  • Path.iterdir() — 현재 디렉터리의 자식들을 열거합니다.
  • Path.is_dir() — 현재 컨텍스트가 디렉터리를 가리키면 True를 반환합니다.
  • Path.is_file() — 현재 컨텍스트가 파일을 가리키면 True를 반환합니다.
  • Path.is_symlink() — 현재 컨텍스트가 심볼릭 링크를 가리키면 True를 반환합니다. (버전 3.12에서 추가 / 버전 3.13에서 변경: 이전에는 is_symlink가 무조건 False를 반환했습니다)
  • Path.exists() — 현재 컨텍스트가 zip 파일 안의 파일이나 디렉터리를 가리키면 True를 반환합니다.
  • Path.suffix — 마지막 구성 요소의 마지막 점으로 구분된 부분(있다면). 보통 파일 확장자라고 합니다. (버전 3.11에서 추가)
  • Path.stem — 접미사 없이 마지막 경로 구성 요소. (버전 3.11에서 추가)
  • Path.suffixes — 경로의 접미사 목록. 보통 파일 확장자라고 합니다. (버전 3.11에서 추가)
  • Path.read_text(*, **) — 현재 파일을 유니코드 텍스트로 읽습니다. 위치·키워드 인자는 io.TextIOWrapper에 전달됩니다 (buffer는 컨텍스트로 암시되므로 제외). (버전 3.11.2에서 변경)
  • Path.read_bytes() — 현재 파일을 bytes로 읽습니다.
  • Path.joinpath(*other) — 각 other 인자가 결합된 새 Path 객체를 반환합니다. 다음은 동등합니다.
    >>> Path(...).joinpath('child').joinpath('grandchild')
    >>> Path(...).joinpath('child', 'grandchild')
    >>> Path(...) / 'child' / 'grandchild'
    
    (버전 3.10에서 변경)

zipp 프로젝트는 최신 path 객체 기능의 백포트를 구형 Python에 제공합니다. 변경 사항에 조기 접근하려면 zipfile.Path 대신 zipp.Path를 쓰세요.

PyZipFile 객체

PyZipFile 생성자는 ZipFile 생성자와 같은 매개변수를 받고, 추가 매개변수 optimize 하나를 더 받습니다.

class zipfile.PyZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, optimize=-1)

버전 3.2에서 변경: optimize 매개변수 추가. 버전 3.4에서 변경: ZIP64 확장이 기본적으로 활성화됨.

인스턴스는 ZipFile 객체의 것이 아닌 추가 메서드 하나를 가집니다.

writepy(pathname, basename='', filterfunc=None)

*.py 파일을 찾고 해당 파일을 아카이브에 추가합니다. PyZipFileoptimize 매개변수가 주어지지 않았거나 -1이면 해당 파일은 *.pyc 파일이며 필요한 경우 컴파일합니다. PyZipFileoptimize 매개변수가 0, 1, 2이면 그 최적화 수준(compile() 참고)을 가진 파일만 아카이브에 추가되며 필요한 경우 컴파일됩니다.

pathname이 파일이면 파일 이름은 .py로 끝나야 하고, 그 (대응하는 *.pyc) 파일만 최상위에 추가됩니다 (경로 정보 없음). pathname.py로 끝나지 않는 파일이면 RuntimeError가 발생합니다. 디렉터리이고 패키지 디렉터리가 아니면 모든 *.pyc 파일이 최상위에 추가됩니다. 패키지 디렉터리이면 모든 *.pyc가 패키지 이름을 파일 경로로 해서 그 아래에 추가되고, 하위 디렉터리가 패키지 디렉터리면 그것들도 모두 정렬된 순서로 재귀적으로 추가됩니다.

basename은 내부 전용으로 의도되었습니다.

filterfunc가 주어지면 단일 문자열 인자를 받는 함수여야 합니다. 아카이브에 추가되기 전에 각 경로(개별 전체 파일 경로 포함)가 전달됩니다. filterfunc가 거짓 값을 반환하면 그 경로는 추가되지 않고, 디렉터리면 그 내용이 무시되어요. 예를 들어 테스트 파일이 모두 test 디렉터리에 있거나 test_ 문자열로 시작한다면, filterfunc로 그것들을 제외할 수 있습니다.

>>> zf = PyZipFile('myprog.zip')
>>> def notests(s):
...     fn = os.path.basename(s)
...     return (not (fn == 'test' or fn.startswith('test_')))
...
>>> zf.writepy('myprog', filterfunc=notests)

writepy() 메서드는 이렇게 생긴 파일 이름으로 아카이브를 만듭니다.

string.pyc                   # Top level name
test/__init__.pyc            # Package directory
test/testall.pyc             # Module test.testall
test/bogus/__init__.pyc      # Subpackage directory
test/bogus/myfile.pyc        # Submodule test.bogus.myfile

버전 3.4에서 변경: filterfunc 매개변수 추가. 버전 3.6.2에서 변경: pathname 매개변수가 path류 객체를 받습니다. 버전 3.7에서 변경: 재귀가 디렉터리 항목을 정렬합니다.

ZipInfo 객체

ZipInfo 클래스의 인스턴스는 ZipFile 객체의 getinfo()infolist() 메서드가 반환합니다. 각 객체는 ZIP 아카이브의 단일 멤버에 대한 정보를 저장해요.

파일시스템 파일에 대한 ZipInfo 인스턴스를 만드는 클래스 메서드가 하나 있습니다.

classmethod ZipInfo.from_file(filename, arcname=None, *, strict_timestamps=True)

zip 파일에 추가할 준비로 파일시스템의 파일에 대한 ZipInfo 인스턴스를 만듭니다. filename은 파일시스템의 파일 또는 디렉터리의 경로여야 해요. arcname이 지정되면 아카이브 안의 이름으로 사용됩니다. 지정되지 않으면 이름은 filename과 같지만 드라이브 문자와 앞의 경로 구분자가 제거됩니다. strict_timestamps 인자를 False로 설정하면 1980-01-01보다 오래된 파일을 타임스탬프를 1980-01-01로 설정하는 대가로 압축할 수 있어요. 2107-12-31보다 새로운 파일에서도 비슷한 동작이 일어나며 타임스탬프가 한계로 설정됩니다. (버전 3.6에서 추가 / 버전 3.6.2에서 변경: filename 매개변수가 path류 객체를 받음 / 버전 3.8에서 변경: 키워드 전용 strict_timestamps 매개변수)

인스턴스는 다음 메서드와 속성을 가집니다.

  • ZipInfo.is_dir() — 이 아카이브 멤버가 디렉터리면 True를 반환합니다. 항목의 이름을 사용하는데, 디렉터리는 항상 /로 끝나야 합니다. (버전 3.6에서 추가)

  • ZipInfo.filename — 아카이브 안의 파일 이름.

  • ZipInfo.date_time — 아카이브 멤버의 마지막 수정 시간과 날짜. ZIP 파일의 중앙 디렉터리의 "last [modified] file time"과 "last [modified] file date" 필드를 나타내는 여섯 값의 튜플입니다.

    인덱스
    0 연도 (>= 1980)
    1 월 (1부터)
    2 일 (1부터)
    3 시 (0부터)
    4 분 (0부터)
    5 초 (0부터)

    참고 — ZIP 형식은 다른 위치(중앙 디렉터리, NTFS/UNIX 시스템용 확장 필드 등)에 여러 타임스탬프 필드를 지원합니다. 이 속성은 구체적으로 중앙 디렉터리의 타임스탬프를 반환해요. ZIP 파일의 중앙 디렉터리 타임스탬프 형식은 1980년 이전의 타임스탬프를 지원하지 않습니다. 일부 확장 필드 형식(UNIX 타임스탬프 등)이 더 이른 날짜를 나타낼 수 있지만, 이 속성은 중앙 디렉터리 타임스탬프만 반환합니다. 중앙 디렉터리 타임스탬프는 다른 zip 도구와 동작을 맞추기 위해 UTC가 아닌 로컬 시간을 나타내는 것으로 해석됩니다.

  • ZipInfo.compress_type — 아카이브 멤버의 압축 유형.

  • ZipInfo.comment — 개별 아카이브 멤버에 대한 bytes 객체의 주석.

  • ZipInfo.extra — 확장 필드 데이터. PKZIP Application Note가 이 bytes 객체에 담긴 데이터의 내부 구조에 대한 주석 몇 가지를 담고 있어요.

  • ZipInfo.create_system — ZIP 아카이브를 만든 시스템.

  • ZipInfo.create_version — ZIP 아카이브를 만든 PKZIP 버전.

  • ZipInfo.extract_version — 아카이브를 추출하는 데 필요한 PKZIP 버전.

  • ZipInfo.reserved — 0이어야 합니다.

  • ZipInfo.flag_bits — ZIP 플래그 비트.

  • ZipInfo.volume — 파일 헤더의 볼륨 번호.

  • ZipInfo.internal_attr — 내부 속성.

  • ZipInfo.external_attr — 외부 파일 속성.

  • ZipInfo.header_offset — 파일 헤더까지의 바이트 오프셋.

  • ZipInfo.CRC — 압축되지 않은 파일의 CRC-32.

  • ZipInfo.compress_size — 압축된 데이터의 크기.

  • ZipInfo.file_size — 압축되지 않은 파일의 크기.

명령줄 인터페이스 (Command-line interface)

zipfile 모듈은 ZIP 아카이브와 상호작용하는 간단한 명령줄 인터페이스를 제공합니다.

새 ZIP 아카이브를 만들려면 -c 옵션 뒤에 이름을 지정하고 포함할 파일 이름을 나열합니다.

$ python -m zipfile -c monty.zip spam.txt eggs.txt

디렉터리를 넘기는 것도 허용됩니다.

$ python -m zipfile -c monty.zip life-of-brian_1979/

ZIP 아카이브를 지정한 디렉터리로 추출하려면 -e 옵션을 씁니다.

$ python -m zipfile -e monty.zip target-dir/

ZIP 아카이브의 파일 목록을 보려면 -l 옵션을 씁니다.

$ python -m zipfile -l monty.zip

명령줄 옵션 (Command-line options)

  • -l <zipfile>, --list <zipfile> — zipfile의 파일을 나열합니다.
  • -c <zipfile> <source1> ... <sourceN>, --create <zipfile> <source1> ... <sourceN> — 소스 파일에서 zipfile을 만듭니다.
  • -e <zipfile> <output_dir>, --extract <zipfile> <output_dir> — zipfile을 대상 디렉터리로 추출합니다.
  • -t <zipfile>, --test <zipfile> — zipfile이 유효한지 테스트합니다.
  • --metadata-encoding <encoding>-l, -e, -t의 멤버 이름 인코딩을 지정합니다. (버전 3.11에서 추가)

압축 해제 함정 (Decompression pitfalls)

zipfile 모듈의 추출은 아래에 나열한 몇 가지 함정 때문에 실패할 수 있어요.

파일 자체로부터 (From file itself)

잘못된 비밀번호 / CRC 체크섬 / ZIP 형식 또는 지원되지 않는 압축 방법 / 복호화 때문에 압축 해제가 실패할 수 있습니다.

파일시스템 한계 (File system limitations)

다른 파일시스템의 한계를 초과하면 압축 해제가 실패할 수 있어요. 디렉터리 항목의 허용 문자, 파일 이름 길이, 경로 이름 길이, 단일 파일 크기, 파일 수 등이 그렇습니다.

리소스 한계 (Resources limitations)

메모리나 디스크 용량 부족은 압축 해제 실패로 이어질 수 있습니다. 예를 들어 압축 해제 폭탄(일명 ZIP 폭탄)은 디스크 용량 고갈을 일으킬 수 있는 zipfile 라이브러리에 적용돼요.

중단 (Interruption)

압축 해제 중 control-C를 누르거나 압축 해제 프로세스를 죽이는 것 같은 중단은 아카이브의 불완전한 압축 해제로 이어질 수 있습니다.

추출의 기본 동작 (Default behaviors of extraction)

기본 추출 동작을 모르면 예상치 못한 압축 해제 결과가 나올 수 있습니다. 예를 들어 같은 아카이브를 두 번 추출하면 묻지 않고 파일을 덮어씁니다.