はじめに
Pythonに、zipfileモジュールがあることを知って、
(zip解凍のフリーソフトやWindows標準のzip解凍機能を知りつつ、あえて)
以下の仕様で、簡易の解凍ツールを作ってみることにしました。
- zipファイルを、DOSバッチにドロップしたら、解凍を実行
- WindowsのPythonは、スクリプト(*.py)に直接ドロップできない
- 出力先フォルダパスは、zipファイルのフルパスから拡張子を取ったもの
- 入力:
[任意フォルダ]\[任意名称].zip
- 出力:
[任意フォルダ]\[任意名称]
- 入力:
- 解凍処理が正常終了したら、DOS窓はすぐ閉じる
- 解凍処理が異常終了したら、DOS窓は終了コードを表示して入力待ち
そうしたら、C#のApplication.exit()
のつもりでコールした
sys.exit()
で数分間ハマったので、メモします。
完成形
とりあえず、先に完成形を示しておきます。
Pythonはインストール済、かつ、Pathが通っている前提です。
各スクリプトのファイル名は決め打ちにしてますが、DOSバッチ内の記述と整合していれば、何でもよいです。
extract.bat
@echo off
cd /d "%~dp0"
:: 本バッチと同じ階層に「extract.py」がある前提
python extract.py -i "%~1"
if errorlevel 1 (
echo.解凍に失敗しました。
echo.ExitCode:%errorlevel%
pause
)
extract.py
from argparse import ArgumentParser
import os
import sys
import zipfile
def main():
parser = ArgumentParser()
parser.add_argument("-i", "--input", default=False, help="Input Zip")
args = parser.parse_args()
filePath = args.input
if (not filePath):
sys.exit(1)
if (not os.path.isfile(filePath)):
sys.exit(2)
folderName = os.path.splitext(os.path.basename(filePath))[0]
outputPath = os.path.join(os.path.dirname(filePath), folderName)
try:
with zipfile.ZipFile(filePath) as zip:
zip.extractall(outputPath)
except:
sys.exit(3)
else:
sys.exit(0)
if (__name__ == "__main__"):
main()
ハマったこと
先に言ってしまうと、以下を知らないまま、ハマり続けました。
どうハマったかは、コードを見たほうが早いですね。
ハマったこと:その1
正常終了時でも、終了コードが3になりました。。。
try:
with zipfile.ZipFile(filePath) as zip:
zip.extractall(outputPath)
sys.exit(0)
except:
sys.exit(3)
ハマったこと:その2
異常終了時でも、終了コードが0になりました。。。
try:
with zipfile.ZipFile(filePath) as zip:
zip.extractall(outputPath)
except:
sys.exit(3)
finally:
sys.exit(0)
終わりに
ハマったおかげで、Pythonのtry-except-else-finallyの動きは、よく分かりました。