Brief Tour of the Standard Library
一通りPythonについて勉強したようなので、最後に標準ライブラリを触っていきます。
Operating System Interface
まずはOSの機能を試してみましょう。
>>> import os >>> os.getcwd() # pwdコマンドと同じ '/home/yohpapa/work/python/tutorial' >>> os.chdir('/home/yohpapa/') # cdコマンドと同じ >>> os.getcwd() '/home/yohpapa' >>> os.system('ls -l') # OS(というかシェル)に直接実行させる total 80 -rw-r--r-- 1 yohpapa yohpapa 1176 2011-01-30 00:19 ChangeLog drwx------ 2 yohpapa yohpapa 4096 2011-02-12 22:19 Desktop drwx------ 5 yohpapa yohpapa 4096 2011-08-19 23:22 Dropbox drwx------ 8 yohpapa yohpapa 4096 2011-01-29 18:35 Mail drwxrwxr-x 2 yohpapa yohpapa 4096 2010-09-24 00:58 Ubuntu One drwxr-xr-x 2 yohpapa yohpapa 4096 2011-08-07 23:42 bin ...
osモジュールの様々な機能は
>>> import os >>> dir(os) ...
で見ることが出来ます。
File Wildcards
カレントディレクトリ (os.getcwd()で確認) のファイル一覧をワイルドカードを使ってフィルタリングしてリスト化することが出来ます。
>>> os.system('ls') doctest.py doctest.pyc dummy-startup.py exception_example.py fibo.py fibo.pyc hogehoge1 test.txt 0 >>> glob.glob('*.py') # ここ! ['dummy-startup.py', 'fibo.py', 'exception_example.py', 'doctest.py']
Command Line Arguments
次にコマンドライン引数を参照してみます (前にもやったような気もしますが) 。
% cat demo.py #!/usr/bin/python2.5 #! -*- coding: utf-8 -*- import sys print sys.argv # ここで引数リストを参照 % python2.5 demo.py a b c d e f g h ['demo.py', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
Error Output Redirection and Program Termination
この手のスクリプト言語では当然ですが、標準エラー出力に出力することが出来ます。スクリプトの標準出力がリダイレクトされている場合に便利です。
>>> sys.stderr.write('Warning, log file not found starting a new one\n') Warning, log file not found starting a new one
String Pattern Matching
文字列のパターンマッチングです。スクリプト言語ではあって当たり前 (?) な感じですね。
>>> import re >>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') ['foot', 'fell', 'fastest'] >>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat') 'cat in the hat'
正規表現が使えるのでかなり強烈なことも出来ます。でも簡単なマッチングをするのであればこんな感じの方が分かりやすい。
>>> 'tea for too'.replace('too', 'two') 'tea for two'
Mathematics
浮動小数点演算用のモジュールです。全然話は変わりますが、私はあまり詳しくはありませんが、数学って好きです。学生のころとても好きだったのが集合と位相です。距離空間やら位相空間の定義を理解出来た (つもりになった) 時は興奮した記憶があります。もちろん今は跡形もなく頭の中から吹き飛んでいますけどね。
閑話休題。こんな感じ。
>>> import math >>> math.cos(math.pi / 4.0) 0.70710678118654757 >>> math.log(1024, 2) 10.0
また、乱数モジュールも整備されているようです。
>>> import random >>> random.choice(['apple', 'pear', 'banana']) # 3つの中からランダムに抽出 'apple' >>> random.sample(xrange(100), 10) # 0〜99の中からランダムに10個抽出 [64, 25, 72, 21, 34, 68, 73, 43, 84, 16] >>> random.random() # 乱数生成 0.73507674202347906 >>> random.randrange(6) # 0〜5の中からランダムに抽出 0
Internet Access
ここではurllib2を使ってみます。App Engineでも見かけるモジュールですね。
>>> import urllib2 >>> for line in urllib2.urlopen('http://kemuohelloworld.appspot.com'): ... print line <html> <head> <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" /> </head> <body> ...
HTTPなどのプロトコルでURLからデータを取得するのに利用されるようです。
Dates and Times
こちらは日付と時刻を扱うためのモジュールです。
>>> now = date.today() >>> print now 2011-08-20 >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") '08-20-11. 20 Aug 2011 is a Saturday on the 20 day of August.'
Data Compression
次にデータ圧縮・解凍のためのモジュールです。いろんな種類のモジュールがあります (zlib, gzip, bz2, zipfile, tarfile) 。試しにzlibを使ってみます。
>>> import zlib >>> s = "I like Android, because of it's openness." >>> len(s) 41 >>> t = zlib.compress(s) >>> len(t) 49 >>> t 'x\x9c\xf3T\xc8\xc9\xccNUp\xccK)\xca\xcfL\xd1QHJMN,-NU\xc8OS\xc8,Q/V\xc8/H\xcd\xcbK-.\xd6\x03\x00&\x9b\x0eY' >>> zlib.decompress(t) "I like Android, because of it's openness."
↑の例では残念なことに圧縮したらサイズが大きくなってしまっていますが、もっと大きなデータの場合、小さくなります。
Performance Measurement
ある処理のパフォーマンス (処理速度) を計測するためのモジュールがいくつかあります (timeit, profile, pstats) 。簡単な処理性能であればtimeitを使えばよいでしょう。
>>> from timeit import Timer >>> Timer('t=a; a=b; b=t', 'a=1; b=2;').timeit() 0.29824304580688477 >>> Timer('a, b = b, a', 'a=1; b=2;').timeit() 0.2480318546295166
でも多分処理速度測る時ってもっと大きなブロックに対してですよね。その場合はprofileやpstatsモジュールを使うことになります。
Quality Control
こちらは単体テスト用のモジュールの紹介。ちなみに私は単体テスト信者です (毎回きちんとやっているということではなく、その重要性を高く認めているだけです・・・やっぱり面倒臭がらずにきちんとやるべきですよね・・・) 。
閑話休題。簡易的な単体テストであれば、こんな感じにdocstring内に書くことが出来ます。
>>> def average(values): ... """Compute the arithmetic mean of a list of numbers. ... >>> average([20, 30, 70]) ... 40.0 ... >>> average([10, 10, 70]) ... 30.0 ... """ ... return sum(values, 0.0) / len(values) >>> doctest.testmod() *** DocTestRunner.merge: '__main__.average' in both testers; summing outcomes. *** DocTestRunner.merge: '__main__' in both testers; summing outcomes. (0, 2)
もちろん単体テストコードを実際のコードと分けて管理することも出来ます。そのような場合はunittestモジュールを利用します。こちらの方が扱いやすいでしょう。