Input and Output

ここではPythonでの入出力の扱い方を学習します。

Fancier Output Formatting

こちらは値をフォーマットする方法です。そもそもPythonでは値を文字列に変換するための関数が備わっています。str()関数とrepr()関数です。

>>> repr(s)
"'Hello, world!'"
>>> str(1.0/7.0)
'0.142857142857'
>>> repr(1.0/7.0)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
>>> print s
The value of x is 32.5, and y is 40000...
>>> hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print hellos
'hello, world\n'
>>> repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"


str()関数は人が見て分かりやすい (human-readable) 表現で文字列に変換されます。repr()関数はインタープリターが解釈する表現で文字列に変換されます。この二つの関数が基本にあります。


その上で、Pythonには大きく分けて2つのフォーマットする方法があります。一つは値を全て文字列化して操作する方法です。もう一つはformat()メソッドを使う方法です。

>>> for x in range(1, 11):
...     print repr(x).rjust(2), repr(x * x).rjust(3),
...     print repr(x * x * x).rjust(4)
... 
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000
>>> for x in range(1, 11):
...     print '{0:2d} {1:3d} {2:4d}'.format(x, x * x, x * x * x)
... 
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000


全て文字列化する方法よりformat()関数を使った方がすっきりしています。個人的にはformat()メソッドを使う方法の方が好きですね。ここではrjust (right-justify) という右側スペースパディング関数を使っていますが、ゼロパディング関数もあります。

>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'


format()メソッドは見ての通り、文字列側の{} (bracket) で囲まれた部分がformat()メソッドの引数に変換されます。中の数値はformat()の引数の出現順序ですね。数値がないと0から順に割り振られます。・・・と思ったら割り振られませんね。バージョンの違いかな?

>>> print 'We are the {} who say "{}!"'.format('knights', 'Ni')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: zero length field name in format


と思ったんですが、さらにPython 2.6以前ではこのformat()メソッドは使えないようです。ということはApp Engine上でも使うことが出来ないわけです。デフォルトで2.6使っていたのに気付きませんでした。これからは2.5を使うようにしないと。ちなみに2.6以前では辞書を使う時は

>>> print 'This %(food)s is %(adjective)s' % {'food': 'spam', 'adjective': 'absolutely horrible'}
This spam is absolutely horrible


のように使います。format()が使えないのは結構きついですね。

Old string formatting

と思ったら書いてありました、「%」演算子。format() 関数がない場合はこの%演算子を使います。C言語のsprintfみたいなもんですね。

>>> print 'The value of PI is approximately %5.3f.' % math.pi
The value of PI is approximately 3.142.


App Engineを開発する場合はこちらになります。

Reading and Writing Files

こちらはファイルへの入出力です。open()関数を使ってファイルを開きます。

>>> f = open('workfile', 'w')
>>> print f
<open file 'workfile', mode 'w' at 0x01642068>
>>> f.close()


第一引数はファイルのパスを指定します。第二引数はファイルオープンモードです。

記号 説明
r 読み込み
w 書き込み (ファイルが存在する場合は中身が消去されます)
a 追記 (ファイルの末尾に追記されていきます)
r+ 読み書き
Methods of File Objects

↑でオープンして取得したファイルオブジェクトを操作していきます。まずは読み込みです。

>>> f = open('workfile.txt', 'r')
>>> f.read()
'This is the entire file.\n'
>>> f.read()
''
>>> f.close()


read()メソッドの引数には読み込みサイズを指定出来ますが、省略されると全データを読み込みます。全てデータを読み込んだ後は''を返します。続いて一行づつ読み込むreadline()メソッドです。

>>> f = open('workfile.txt', 'r')
>>> f.readline()
'This is the entire file.\n'
>>> f.readline()
'Second line of the file.\n'
>>> f.readline()
''
>>> f.close()


こちらも全ての行を読み込むと''が返ります。またreadlines()メソッドは読み込んだ各行をリストにして返します。

>>> f = open('test.txt','r')
>>> f.readlines()
['This is the first line of file.\n', 'Second line of the file.\n']
>>> f.close()


for文の中ではかなり便利に使えます。

>>> f = open('test.txt','r')
>>> for line in f:
...     print line
... 
This is the first line of file.

Second line of the file.

>>> f.close()


これはRubyでよく見かけた書き方です。そして当然データを書き込むことが可能です。

>>> f = open('test.txt','r+')
>>> for line in f:
...     print line
... 
This is the first line of file.

Second line of the file.

>>> f.write('This is a test.\n')  # 3行めに'This is a test.\n'を追記
>>> f.close()
>>> exit()
% cat test.txt
This is the first line of file.
Second line of the file.
This is a test.


また、C言語と同じようにtell()やseek)メソッドがあります。tell()が現在のファイルポインタの位置を返し、seekメソッドは現在の位置を変更します。もちろんいつものように

説明
0 ファイルの先頭から
1 現在の位置から
2 ファイルの末尾から


となります。

The pickle Module

Pythonでのファイルへの入出力は全て文字列で行われます。なので数値が欲しい場合はint()メソッドなどで文字列を数値に変換する必要があります。ではファイル内に辞書やリストなどのオブジェクトを書き込みたい場合はどうすればよいでしょうか?そこで登場するのがpickleモジュールです。オブジェクトを文字列に変換したり (picklingといいう) 、逆に文字列からオブジェクトを生成したり出来ます (unpicklingという) 。シリアライザといったところでしょうかね。