このセクションでは、一般的な問題を解決するための Python の多数の標準ユーティリティ モジュールをいくつか見ていきます。
ファイルシステム -- os、os.path、Shutil
*os* モジュールと *os.path* モジュールには、ファイル システムとやり取りするための多くの関数が含まれています。*shutil* モジュールはファイルをコピーできます。
- OS モジュール ドキュメント
- filenames = os.listdir(dir) -- そのディレクトリパス内のファイル名のリスト(.など)。ファイル名はディレクトリ内の名前であり、絶対パスではありません。
- os.path.join(dir, filename) -- 上記のリストのファイル名を指定して、これを使用してディレクトリとファイル名を組み合わせてパスを作成します。
- os.path.abspath(path) -- パスを指定すると絶対形式を返します。例:/home/nick/foo/bar.html
- os.path.dirname(path), os.path.basename(path) -- 指定された dir/foo/bar.html は、ディレクトリ名「dir/foo」を返します。ベース名「bar.html」
- os.path.exists(path) -- 存在する場合は true
- os.mkdir(dir_path) -- 1 つのディレクトリを作成し、os.makedirs(dir_path) はこのパスに必要なすべてのディレクトリを作成する
- switchil.copy(source-path, dest-path) -- ファイルをコピーします(接続先パスのディレクトリが存在している必要があります)
## Example pulls filenames from a dir, prints their relative and absolute paths def printdir(dir): filenames = os.listdir(dir) for filename in filenames: print(filename) ## foo.txt print(os.path.join(dir, filename)) ## dir/foo.txt (relative to current dir) print(os.path.abspath(os.path.join(dir, filename))) ## /home/nick/dir/foo.txt
モジュールの探索は、組み込みの Python help() および dir() 関数を使用するとうまく機能します。インタープリタで「import os」を実行し、モジュール dir(os)、help(os.listdir)、dir(os.path)、help(os.path.dirname) のコマンドを使用して、モジュールで利用可能なものを確認します。
外部プロセスの実行 -- サブプロセス
*subprocess* モジュールを使用すると、簡単に外部コマンドを実行して出力を取得できます。
- サブプロセス モジュールのドキュメント
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) -- コマンドを実行して終了するまで待機し、出力テキストを返します。このコマンドは、標準出力と標準エラーが 1 つの出力テキストに結合された状態で実行されます。失敗した場合は、CalledProcessError がスローされます。
- サブプロセスの実行をより詳細に制御する必要がある場合は、subprocess.popen クラスをご覧ください。
- また、シンプルな subprocess.call(cmd) を使用して、コマンドを実行し、その出力を出力にダンプしてエラーコードを返します。これは、コマンドを実行したいが、その出力を Python データ構造にキャプチャする必要がない場合に機能します。
import subprocess ## Given a dir path, run an external 'ls -l' on it -- ## shows how to call an external program def listdir(dir): cmd = 'ls -l ' + dir print("Command to run:", cmd) ## good to debug cmd before actually running it (status, output) = subprocess.getstatusoutput(cmd) if status: ## Error case, print the command's output to stderr and exit sys.stderr.write(output) sys.exit(status) print(output) ## Otherwise do something with the command's output
例外
例外は、特定の行で通常の実行を停止し、エラー処理コードに制御を移すランタイム エラーを表します。このセクションでは、例外の最も基本的な用途についてのみ説明します。たとえば、ランタイム エラーとしては、プログラムで使用されている変数に値がない(ValueError など、何度か見たことがあるかもしれません)、ファイルが存在しないことによるファイル オープン オペレーション エラー(IOError)などがあります。詳しくは、例外のチュートリアルと例外リスト全体をご覧ください。
これまでに行ったように、エラー処理コードがなければ、ランタイム例外はプログラムを停止してエラー メッセージを表示します。これは良いデフォルトの動作であり、何度も目にしています。「try/except」句を構造を記述して、例外を処理することができます。
try: ## Either of these two lines could throw an IOError, say ## if the file does not exist or the read() encounters a low level error. f = open(filename, 'rb') data = f.read() f.close() except IOError: ## Control jumps directly to here if any of the above lines throws IOError. sys.stderr.write('problem reading:' + filename) ## In any case, the code then continues with the line after the try/except
try: セクションには、例外をスローする可能性のあるコードが含まれています。例外: セクションには、例外が発生した場合に実行するコードが保持されます。例外がない場合、except: セクションはスキップされます(つまり、このコードはエラー処理専用であり、コードの「通常の」ケースではありません)。例外オブジェクト自体へのポインタを取得するには、「except IOError as e: ..」という構文を使用します。(e は例外オブジェクトを指します)。
HTTP -- urllib と urlparse
*urllib.request* モジュールは URL 取得機能を備えており、読み取れるファイルのように URL を作成できます。*urlparse* モジュールは、分割して URL をまとめることができます。
- urllib.request モジュールのドキュメント
- ufile = urllib.request.urlopen(url) -- その URL のオブジェクトのようなファイルを返します。
- text = ufile.read() -- ファイルのようにそこから読み取ることができます(readlines() なども機能します)
- info = ufile.info() -- そのリクエストのメタ情報。info.gettype() は、MIME タイプです。次に例を示します。「text/html」
- baseurl = ufile.geturl() -- 「ベース」を取得リクエストの URL。リダイレクト先の URL とは異なる場合があります。
- urllib.request.urlretrieve(url, filename) -- 指定されたファイルパスに URL データをダウンロードします。
- urllib.parse.urljoin(baseurl, url) -- 完全な URL とは限らず、またそのページのベース URL を指定すると、完全な URL を返します。上記の geturl() を使用してベース URL を指定します。
例外はすべて urllib.error に記載されています。
from urllib.request import urlopen ## Given a url, try to retrieve it. If it's text/html, ## print its base url and its text. def wget(url): ufile = urlopen(url) ## get file-like object for url info = ufile.info() ## meta-info about the url content if info.get_content_type() == 'text/html': print('base url:' + ufile.geturl()) text = ufile.read() ## read all its text print(text)
上記のコードは正常に機能しますが、なんらかの理由で URL が機能しない場合のエラー処理は含まれません。URL オペレーションが失敗した場合にエラー メッセージを出力する try/except ロジックを追加する関数のバージョンを次に示します。
urlopen()
がハングしていると思われる場合、システムによって一部への直接アクセスが許可されていない可能性があります
通信できます。これを確認するには、wget
を使用して同じ URL を取得します。
curl
。これらのプログラムも失敗した場合は、プロキシ経由で HTTP コンテンツを取得する必要があります。
あります。このチュートリアルでは、プロキシ アクセスの構成については説明しません。
## Version that uses try/except to print an error message if the ## urlopen() fails. def wget2(url): try: ufile = urlopen(url) if ufile.info().get_content_type() == 'text/html': print(ufile.read()) except IOError: print('problem reading url:', url)
エクササイズ
ファイル システムと外部コマンドの演習については、特別な演習のコピーをご覧ください。urllib の資料を練習するには、ログパズルの演習をご覧ください。