Python Utilities in Google's Python Class in Japanese

Google による Python の授業 (日本語訳)/ Google's Python Class (英語原文)

資料
日本語訳: 設定/ 入門/ 文字列/ リスト/ 整列/ 辞書とファイル/ 正規表現/ ユーティリティ
英語原文: Set Up/ Introduction/ Strings/ Lists/ Sorting/ Dict and Files/ Reg. Exp./ Utilities

練習問題
日本語訳: 基本問題/ 新生児名/ 特殊なコピー/ アクセス履歴のパズル
英語原文: Basic Exercises/ Baby Names Exercise/ Copy Special Exercise/ Log Puzzle Exercise

講義映像
英語
1日目: Introduction, Strings/ Lists and Sorting/ Dicts and Files
2日目: Regular Expression/ Utilities/ Utilities urllib/ Conclusions

Python ユーティリティ


この節では, 良くある問題を解くためにある, 多くの標準的なユーティリティモジュールのうちのいくつかを見ていきます.

ファイルシステム -- os, os.path, shutil


*os*, *os.path* モジュールには, ファイルシステムとやり取りする 多くの関数があります. *shutil* モジュールはファイルをコピーできます.
  • os モジュールに関する文章 (英語)
  • filenames = os.listdir(dir) -- そのディレクトリパス dir にあるファイル名のリスト (. と .. は含みません). ファイル名はそのディレクトリにある名前だけで, 絶対パスではありません.
  • os.path.join(dir, filename) -- 上のリストからファイル名 filename が与えられたとき, パスを作るためにディレクトリとファイル名を一緒にするのに使います.
  • os.path.abspath(path) -- パスが与えられたとき, /home/nick/foo/bar.html のように絶対パスを返します.
  • os.path.dirname(path), os.path.basename(path) -- dir/foo/bar.html が与えられたとき, dirname は "dir/foo", basename は "bar.html" をそれぞれ返します.
  • os.path.exists(path) -- パス path があるなら真になります.
  • os.mkdir(dir_path) -- ディレクトリを 1つ作ります. os.makedirs(dir_path) は dir_path に必要なディレクトリをすべて作ります.
  • shutil.copy(source-path, dest-path) -- ファイルをコピーします (コピー先のディレクトリ dest-path は存在するものを指定します)
## あるディレクトリのファイル名に対して, その相対パスと絶対パスを表示する例
def printdir(dir):
  filenames = os.listdir(dir)
  for filename in filenames:
    print filename  ## foo.txt
    print os.path.join(dir, filename) ## dir/foo.txt (現在のディレクトリからの相対パス)
    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).

外部プロセスの実行 -- commands


*commands* モジュールは外部コマンドを実行し, 出力結果を取り込むのに 簡単な方法です.
  • commands モジュールの文章
  • (status, output) = commands.getstatusoutput(cmd) -- コマンドを実行し, その終了まで待ち, 終了状態を整数で, 出力されたテキストを タプルで返します. そのコマンドが実行されるとき, 標準出力とエラー出力が混ざって 1つの出力テキストになります. コマンドの実行が失敗したとき, 終了状態の値は 0以外になります. コマンドのエラー出力を取り込んでいるので, コマンド実行が失敗したときは 何が起こったかの表示を出力する必要があります.
  • output = commands.getoutput(cmd) -- 上と同じですが, 終了状態の整数値がありません.
  • commands.getstatus() というコマンドもありますが, 思慮の足りない名づけ方のため, 違う動作をするので使わないこと.
  • 子プロセスの実行をもっと制御したいなら, "popen2" モジュール (http://docs.python.org/lib/module-popen2.html) を参照すること.
  • コマンドを実行し, そのコマンドの出力結果をまとめて Python での出力とし, エラーコードを返す, 簡単な os.system(cmd) もあります. これは, コマンドを実行したいが, 出力を Python のデータ構造に取り込む必要が ないときに使えます.
## ディレクトリのパス dir が与えられたとき, 外部コマンド 'ls -l' を dir で
## 実行する外部プログラムの呼び方を示します. 
def listdir(dir):
  cmd = 'ls -l ' + dir
  print "Command to run:", cmd   ## 実際に実行する前に cmd の間違いを確認できます. 
  (status, output) = commands.getstatusoutput(cmd)
  if status:    ## エラーの場合, コマンドの出力を stderr に出力し, 終了. 
    sys.stderr.write(output)
    sys.exit(1)
  print output  ## それ以外はコマンドの出力を使った処理

例外


例外は, ある特定の行で通常の実行を停止させる実行時エラーを表し, 制御をエラー処理コードに渡します. この節では, 例外の最も基本的な使い方を紹介します. 実行時エラーは例えば, プログラムで使われる変数が値を持っていないこと (ValueError .. 何度かこれを目にしているでしょう) や 存在しないファイルを開こうとする操作のエラー (IOError) があります. (例外に関する文章 を参照)
(これまで行ってきたように) エラー処理コードがないと, 実行時エラーはエラーメッセージを表示してプログラムを停止させるだけです. これが初期設定の振る舞いで, これまで何度も見てきたものです. 例外を処理するためには, 次のようにコードに "try/except" 構造を加えられます.
  try:
    ## 次の 2行のどちらかで IOError が起きるかもしれません. 
    ## 例えば, 指定したファイルがない, read() が下層のエラーに見舞われる, など. 
    f = open(filename, 'rU')
    text = f.read()
    f.close()
  except IOError:
    ## もし上の行のどこかで IOError が起きたら, 制御が直接ここに飛びます. 
    sys.stderr.write('problem reading:' + filename)
  ## どの場合でも, その try/except の後の行から実行が続きます. 

try: の部分には, 例外が起きる可能性のあるコードが入っています. except: の部分には, 例外があったときに実行されるコードがあります. 例外が起きないときには, except: の部分は飛ばされます (つまり, except: 部分のコードはエラー処理のためだけのもので, "通常" の場合のものではありません).

HTTP -- urllib と urlparse


モジュール *urllib* には URL 取得に関する機能があり, URL を可読性のあるファイルのように扱えます. *urlparse* モジュールは URL を解析したり, まとめたりします.
  • urllib モジュールの文章 (英語)
  • ufile = urllib.urlopen(url) -- url で表されるオブジェクトをファイルのような扱いで返します.
  • text = ufile.read() -- そのオブジェクトをファイルのように読み取れます (readlines() なども使えます)
  • info = ufile.info() -- その要求に対するメタ情報です. info.gettype() は 'text/html' といった mime 型です.
  • baseurl = ufile.geturl() -- 要求に対する "基本" URL を取得します. 転送により元の URL とは異なる場合があります.
  • urllib.urlretrieve(url, filename) -- 与えられたファイルパス (filename) に URL (url) のデータをダウンロードします.
  • urlparse.urljoin(baseurl, url) -- 完全かどうか不明な URL (url) とそのページの基本 URL (baseurl) が与えられたとき, 完全な URL を返します. 基本 URL を得るには geturl() を使うこと.
## URL が与えられると, その内容を取得しようとします. もしそれが text/html なら, 
## その基本 URL とテキストを表示します. 
def wget(url):
  ufile = urllib.urlopen(url)  ## url に対してファイルのようなオブジェクトを取得します. 
  info = ufile.info()   ## url の内容に関するメタ情報
  if info.gettype() == 'text/html':
    print 'base url:' + ufile.geturl()
    text = ufile.read()  ## テキストをすべて読みます
    print text

上のコードは動作しますが, 何らかの理由である URL が機能しないときの エラー処理を含んでいません. URL の操作が失敗したときにエラーメッセージを表示する try/except の仕組みを加えた改良版の関数です.
## urlopen() が失敗したときにエラーメッセージを
## 表示する try/except を使う改良版
def wget2(url):
  try:
    ufile = urllib.urlopen(url)
    if ufile.info().gettype() == 'text/html':
      print ufile.read()
  except IOError:
    print 'problem reading url:', url

練習問題


ファイルシステムと外部コマンドの内容を練習するために, Copy Special Exercise (英語原文), 特殊なコピーの問題を見ること. urllib の内容を練習するために, Log Puzzle Exercise (英語原文), サーバの履歴を使ったパズルの問題を見ること.
この資料は Google の Nick Parlante によって作成されたものの翻訳です. Google による Python の授業の文章と映像は Creative Commons Attribution 2.5 ライセンスの下で利用できます.