Pythonクックブックを読んでいる(2)
2009年2月21日
1. fileオブジェクトをそのままループできる
こんな風に書けるそうで。
こんな風に書けるそうで。
f = open('/path/to/filename', 'r') for line in f: print line
fileオブジェクトはジェネレータなので、
readやreadlinesで一回で全部読み込むのとは違い、
メモリ消費が少なくて済むというメリットがある。
超巨大ファイルを処理する場合は、こっちの方がいいすな。
2. fileへの書き込みが保障されるのはcloseした時
そういえば、過去自分が書いたバッチの話なんですが、
“a”モードで開いたファイルに対して、closeなしに延々追記をしてたときに、
実際にHD上のテキストファイルに反映されるのが、スクリプトの進行より遅かったことがある。
こういう仕組みだったのか。
そういえば、過去自分が書いたバッチの話なんですが、
“a”モードで開いたファイルに対して、closeなしに延々追記をしてたときに、
実際にHD上のテキストファイルに反映されるのが、スクリプトの進行より遅かったことがある。
こういう仕組みだったのか。
3. str.replace
print "abcdeabcde".replace("b", "B") # -> "aBcdeaBcde"
このメソッド知らなかった・・・。
同じことするのに、re.subとかでやってたぜ金返せ!
4. stdin, stdout
標準入力/標準出力制御をできる。
例えば標準入力の場合は、こんな風に書けば
標準入力/標準出力制御をできる。
例えば標準入力の場合は、こんな風に書けば
for line in sys.stdin: print line.rstrip()
OSから標準入力を受け付けることができる。
$echo "111\n222\n333" | ./filename.py
なお、sys.stdin, sys.stdout 両方ともfileライクオブジェクト。
5. timeitモジュール
簡単なスクリプトの実行時間計測モジュール。
Pythonソースを文字列で渡さないといけないのが、やや気持ち悪いけど、
簡単なスクリプト用としては、これがベストだろうなぁ。
簡単なスクリプトの実行時間計測モジュール。
Pythonソースを文字列で渡さないといけないのが、やや気持ち悪いけど、
簡単なスクリプト用としては、これがベストだろうなぁ。
と、テストがてら、前回の文字列連結の時間計測をしてみた。
import timeit source = """ s = "1" + ", 2" + ", 3" + " da---!" """ timer = timeit.Timer(stmt=source) print "join: ", timer.timeit(10000) # 試行回数 source = """ s = "%s, %s, %s da---!" % (1, 2, 3) """ timer = timeit.Timer(stmt=source) print "format: ", timer.timeit(10000)
じゃん、結果!
join: 0.0010929107666 format: 0.0233690738678
・・・あれっ?フォーマットの方が遅いんだけど・・・・・
・・・・・・ま、まぁいいや、見なかったことにしよう・・・。
(つーか、timeitの使い方が間違ってたら元も子もないな)
6. os.tmpfile()
一時ファイルを作成できる、一時ファイルはcloseするとGC対象になる。
使いどころは、巨大データをメモリ上から退避させて、ゆっくり処理する時とかだろうか。
一時ファイルを作成できる、一時ファイルはcloseするとGC対象になる。
使いどころは、巨大データをメモリ上から退避させて、ゆっくり処理する時とかだろうか。
tf = os.tmpfile() # 少しずつ膨れ上がるデータをメモリから退避 for c in "1GB data": tf.write(c) # 読み込みのためにファイルポインタを頭に戻す tf.seek(0) # 今度は少しずつ先のファイルを読み込み new_data = "" while True: c = tf.read(1) new_data += c.replace("G", "M") if not c: break tf.close() print new_data # -> "1MB data"
こんな感じ?
あれ、closeしないとHD上への書き込みは保存されないんだっけか・・・?
・・・と、ググったけど、tmpfileを使ったサンプルが出てこないのでとりあえず保留。
実際使うときになったら、標準モジュールとかDjangoとかから探そうっと。
7. os.walk()
指定パスから、再帰的に全てのファイルとディレクトリを返してくれる。
こりゃあ、便利だねっ!
同じような関数を自分で書いちゃったなー。
指定パスから、再帰的に全てのファイルとディレクトリを返してくれる。
こりゃあ、便利だねっ!
同じような関数を自分で書いちゃったなー。
以上。
色々、挙動が不明の場所もありましたが、
そこはそれ、スルー力には自信がある。