Pythonクックブック(2章)

ファイル操作の続き

zipファイルを扱う(zipfile, tempfile)

zipfileモジュールを使うとzipファイルの内容物を表示したり、展開したりできる。

ZipFile.namelist()を使うと内容物の名前を取得できるけど、
ZipFile.infolist()を使うと内容物に関する名前とかサイズとか更新日なんかも取得できる。

>>> import zipfile
>>> z = zipfile.ZipFile("xml_parse.zip", "r")
>>> for info in z.infolist():
...   print 'File:', info.filename, 'has', info.file_size, 'bytes'
... 
File: xml_parse/ has 0 bytes
File: xml_parse/comps.xml has 1726498 bytes
File: xml_parse/filelists.xml has 35256400 bytes
File: xml_parse/sax_parser.py has 6532 bytes
>>> 

tempfileモジュールを使うと一時ファイルを作成することが出来る。
tempfile.mkstemp()を使うと一時ファイルを作成できるけど、使い終わったら自分で消さないといけない。
tempfile.NamedTemporaryFile()だと使い終わったら自動的に消してくれる。
tempfile.NamedTemporaryFile()とtempfile.TemporaryFile()の違いは、ファイルの名前があるのかないのか。

>>> import zipfile, tempfile, sys
>>> file = tempfile.NamedTemporaryFile(mode='w+t', suffix='.zip')
>>> file.name
'/tmp/tmpcbTHIk.zip'
>>> z = zipfile.ZipFile(file.name, 'w')
>>> z.writestr('hello.py', 'def f(): return "hello world from "+__file__\n')
>>> z.close()
>>> sys.path.insert(0, file.name)
>>> import hello
>>> print hello.f()
hello world from /tmp/tmpcbTHIk.zip/hello.py
>>> 

でもなんで/tmp/tmpcbTHIk.zip内のhello.pyを直接インポートできるのかわからない。
zipfileモジュールを一切介さずインポートしようとするとエラーが出るから、zipfileモジュールが関連してるんだろうな。

>>> import sys
>>> sys.path.insert(0, '/home/kobakoba0723/hello_world.zip')
>>> import hello
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named hello
>>> 
[kobakoba0723@fedora13-intel64 ~]$ ls
TestTool      cedet-1.0.tar.gz  lib                テンプレート  画像
TestTool.bak  exec.data         search_string      デスクトップ  公開
anaconda      ez_setup.py       virtual-python.py  ドキュメント
bin           hello_world.zip   xml_parse.zip      ビデオ
cedet-1.0     include           ダウンロード       音楽
[kobakoba0723@fedora13-intel64 ~]$ unzip hello_world.zip 
Archive:  hello_world.zip
   creating: hello_world/
  inflating: hello_world/hello.py    
[kobakoba0723@fedora13-intel64 ~]$ 

tarファイルを扱う(tarfile)

tarfileモジュールを使うことで、作成から展開まで行える。

[kobakoba0723@fedora13-intel64 ~]$ cat make_tar.py 
import tarfile
import os


def make_tar(folder_to_backup, dest_folder, compression='gz'):
    if compression:
        dest_ext = '.' + compression
    else:
        dest_ext = ''
    arcname = os.path.basename(folder_to_backup)
    dest_name = '%s.tar%s' % (arcname, dest_ext)
    dest_path = os.path.join(dest_folder, dest_name)
    if compression:
        dest_cmp = ':' + compression
    else:
        dest_cmp = ''
    out_file = tarfile.open(dest_path, 'w' + dest_cmp)
#    out_file.add(folder_to_backup)
    out_file.add(folder_to_backup, arcname)
    out_file.close()
    return dest_path


def listup_tar(filename):
    in_file = tarfile.open(filename, 'r')
    print in_file.list()


def unpack_tar(filename):
    in_file = tarfile.open(filename, 'r')
    in_file.extractall(path='./unpack')


if __name__ == '__main__':
    filename = make_tar('/home/kobakoba0723/search_string',
                        '/home/kobakoba0723/',
                        'gz'
                       )
    print filename
    listup_tar(filename)
    unpack_tar(filename)

tarfile.addの第2引数を指定しなければ、dest_pathをトップから全てzipにしてくれる。
第2匹数を指定すれば、指定したところからzipにしてくれる

[kobakoba0723@fedora13-intel64 ~]$ ls
TestTool      cedet-1.0         include        unpack             デスクトップ  画像
TestTool.bak  cedet-1.0.tar.gz  lib            virtual-python.py  ドキュメント  公開
anaconda      exec.data         make_tar.py    ダウンロード       ビデオ
bin           ez_setup.py       search_string  テンプレート       音楽
[kobakoba0723@fedora13-intel64 ~]$ ls unpack/
[kobakoba0723@fedora13-intel64 ~]$ python make_tar.py 
/home/kobakoba0723/search_string.tar.gz
-rwxrwxr-x kobakoba0723/kobakoba0723          0 2011-06-22 23:02:23 search_string/
-rw-rw-r-- kobakoba0723/kobakoba0723         56 2011-04-10 18:14:20 search_string/snmpd.options
-rw-r--r-- kobakoba0723/kobakoba0723       1549 2011-04-10 17:26:47 search_string/profile
-rw-rw-r-- kobakoba0723/kobakoba0723        547 2011-04-10 18:26:35 search_string/search_string.py
None
[kobakoba0723@fedora13-intel64 ~]$ ls unpack/
search_string
[kobakoba0723@fedora13-intel64 ~]$

参考サイト

モジュールインデックス@Python 2.6.2 document

Python クックブック 第2版

Python クックブック 第2版