Python 3 の入力と出力

前の節では、Pythonの入力と出力機能に触れました。 この節では、Pythonの入力と出力について具体的に紹介します。

出力フォーマットを美化する

Pythonには、式ステートメントとprint()関数の2つの値の出力方法があります。

3番目の方法は、ファイルオブジェクトのwrite()メソッドを使用することです。標準出力ファイルは、sys.stdoutで参照できます。

より多様な出力フォーマットが必要な場合は、str.format()関数を使用して出力値を初期化できます。

出力値を文字列に変換する場合は、repr()またはstr()関数を使用してそれを実現できます。

  • str():この関数はユーザーが読み取り可能な式を返します。
  • repr():インタープリターの読み取り可能なフォームを生成します。

>>> s = 'Hello, Ceodata'
>>> str(s)
'Hello, Ceodata'
>>> repr(s)
"'Hello, Ceodata'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'x の値は: ' + repr(x) + ',  y の値は:' + repr(y) + '...'
>>> print(s)

x の値は: 32.5,  y の値は:40000...

>>> # repr()関数は文字列内の特殊文字をエスケープできる
... hello = 'hello, Ceodata\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, Ceodata\n'
>>> # repr()のパラメーターはPythonの任意のオブジェクトにすることができる
... repr((x, y, ('Google', 'Ceodata')))
"(32.5, 40000, ('Google', 'Ceodata'))"

二つの方法で二次方と三次方のテーブルを出力します。

>>> for x in range(1, 11):
...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
...     # 前の行での「end」の使用に注意してください
...     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

注:最初の例では、各列の間のスペースはprint()によって追加されます。

この例は、文字列オブジェクトのrjust()メソッドを示しています。このメソッドは、文字列を右に移動し、左側にスペースを入れることができます。

ljust()やcenter()などの同様のメソッドがあります。 これらのメソッドは何も書き込まず、新しい文字列を返すだけです。

別のメソッドzfill()は、以下に示すように、数値の左側に0を入力します。

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

str.format()の基本的な使用方法は次のとおりです。

>>> print('{}URL: "{}!"'.format('初心者チュートリアル', 'www.ceodata.com'))
初心者チュートリアルURL: "www.ceodata.com!"

括弧とその中の文字(フォーマットフィールドと呼ばれる)は、format()のパラメータに置き換えられます。

括弧内の数字は、以下に示すように、format()で渡されたオブジェクトの位置を指すために使用されます。

>>> print('{0} と {1}'.format('Google', 'Ceodata'))
Google と Ceodata
>>> print('{1} と {0}'.format('Google', 'Ceodata'))
Ceodataと Google

キーワードパラメータがformat()で使用されている場合、それらの値はその名前のパラメータを指します。

>>> print('{name}URL: {site}'.format(name='初心者チュートリアル', site='www.ceodata.com'))
初心者チュートリアルURL: www.ceodata.com

位置とキーワードパラメータは任意に組み合わせることができます。

>>> print('サイトリスト {0}, {1}, と {other}。'.format('Google', 'Ceodata', other='Yahoo'))
サイトリスト Google, Ceodata, と Yahoo。

!a(ascii()を使用)、! s(str()を使用)、および!r(repr()を使用)を使用して、値をフォーマットする前に変換できます。

>>> import math
>>> print('定数PIの値は約: {}。'.format(math.pi))
定数PIの値は約: 3.141592653589793。
>>> print('定数PIの値は約: {!r}。'.format(math.pi))
定数PIの値は約: 3.141592653589793。

オプション:フォーマット識別子の後にフィールド名をつけることができます。 これにより、値のフォーマットが改善されます。 次の例では、円周率を小数点以下3桁に保留します。

>>> import math
>>> print('定数PIの値は約 {0:.3f}。'.format(math.pi))
定数PIの値は約 3.142。

“ : ”の後に整数を渡します。フィールドの幅が少なくともそれだけになるようにします。 テーブルの美化に役立ちます。

>>> table = {'Google': 1, 'Ceodata': 2, 'Yahoo': 3}
>>> for name, number in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, number))
... 
Google     ==>          1
Ceodata     ==>          2
Yahoo     ==>          3

非常に長いフォーマット文字列があり、それらを分離したくない場合は、フォーマット時に位置の代わりに変数名を渡すことをお勧めします。

最も簡単な方法は、辞書を渡し、角かっこ[]を使用してキー値にアクセスすることです。

>>> table = {'Google': 1, 'Ceodata': 2, 'Yahoo': 3}
>>> print('Ceodata: {0[Ceodata]:d}; Google: {0[Google]:d}; Yahoo: {0[Yahoo]:d}'.format(table))
Ceodata: 2; Google: 1; Yahoo: 3

テーブル変数の前に**を使用して、同じ機能を実現できます。

>>> table = {'Google': 1, 'Ceodata': 2, 'Yahoo': 3}
>>> print('Ceodata: {Ceodata:d}; Google: {Google:d}; Yahoo: {Yahoo:d}'.format(**table))
Ceodata: 2; Google: 1; Yahoo: 3

古いスタイルの文字列フォーマット

%演算子は、文字列のフォーマットを実装することもできます。 左側のパラメータをsprintf()と同様のフォーマットされた文字列として受け取り、右側のパラメータを置き換えて、フォーマットされた文字列を返します。次に例を示します。

>>> import math
>>> print('定数PIの値は約:%5.3f。' % math.pi)
定数PIの値は約:3.142。

str.format()は比較的新しい関数であるため、ほとんどのPythonコードは引き続き%演算子を使用します。 ただし、この古いスタイルのフォーマットは最終的に言語から削除されるため、str.format()をより多く使用すべきです。

キーボード入力の読み取り

Pythonには、標準入力から1行のテキストを読み取るためのinput()組み込み関数が用意されています。デフォルトの標準入力はキーボードです。

inputは、Python式を入力として受け取り、操作の結果を返します。

実例

#!/usr/bin/python3

str = input("入力してください:");
print ("入力した内容: ", str)

これにより、入力に対応する次の結果が生じます。

入力してください:初心者チュートリアル

入力した内容:初心者チュートリアル

ファイルの読み取りと書き込み

open()はfileオブジェクトを返します。基本的な構文形式は次のとおりです。

  • filename:アクセスするファイル名の文字列値が含まれています。
  • mode:ファイルを開くモードを決定します。読み取り専用、書き込み、追加などです。 可能なすべての値については、以下のリストを参照してください。 このパラメータは必須ではなく、デフォルトのファイルアクセスモードは読み取り専用(r)です。

さまざまなモードで開いているファイルのリスト

モード説明
rファイルを読み取り専用として開きます。 ファイルのポインタはファイルの先頭に配置されます。 これがデフォルトのモードです。
rb読み取り専用のバイナリ形式でファイルを開きます。 ファイルポインタはファイルの先頭に配置されます。
r+読み取りと書き込み用にファイルを開きます。 ファイルポインタはファイルの先頭に配置されます。
rb+読み取りと書き込みのためにバイナリ形式でファイルを開きます。 ファイルポインタはファイルの先頭に配置されます。
w書き込み専用のファイルを開きます。 ファイルが既に存在する場合は、ファイルを開いて最初から編集を開始します。つまり、元のコンテンツが削除されます。 ファイルが存在しない場合は、新しいファイルを作成します。
wb書き込み専用のバイナリ形式でファイルを開きます。 ファイルが既に存在する場合は、ファイルを開いて最初から編集を開始します。つまり、元のコンテンツが削除されます。 ファイルが存在しない場合は、新しいファイルを作成します。
w+読み取りと書き込み用にファイルを開きます。ファイルが既に存在する場合は、ファイルを開いて最初から編集を開始します。つまり、元のコンテンツが削除されます。ファイルが存在しない場合は、新しいファイルを作成します。
wb+読み取りと書き込みのためにバイナリ形式でファイルを開きます。ファイルが既に存在する場合は、ファイルを開いて最初から編集を開始します。つまり、元のコンテンツが削除されます。ファイルが存在しない場合は、新しいファイルを作成します。
a追加するファイルを開きます。ファイルがすでに存在する場合、ファイルポインタはファイルの最後に配置されます。つまり、新しいコンテンツは既存のコンテンツの後に書き込まれます。ファイルが存在しない場合は、書き込み用に新しいファイルを作成します。
ab追加するためにバイナリ形式でファイルを開きます。ファイルがすでに存在する場合、ファイルポインタはファイルの最後に配置されます。つまり、新しいコンテンツは既存のコンテンツの後に書き込まれます。ファイルが存在しない場合は、書き込み用に新しいファイルを作成します。
a+読み取りと書き込み用にファイルを開きます。ファイルがすでに存在する場合、ファイルポインタはファイルの最後に配置されます。ファイルを開くと、追加モードになります。ファイルが存在しない場合は、読み取りと書き込み用に新しいファイルを作成します。
ab+追加するためにバイナリ形式でファイルを開きます。ファイルがすでに存在する場合、ファイルポインタはファイルの最後に配置されます。ファイルが存在しない場合は、読み取りと書き込み用に新しいファイルを作成します。

次の図は、これらのモードをうまく要約しています。

モードrr+ww+aa+
読み取り +++++
書き込み+++++
作成++++
カバー++
ポインタが最初にある++++
ポインタが最後にある++

次の例では、ファイルfoo.txtに文字列を書き込みます。

実例

#!/usr/bin/python3

# ファイルを開く
f = open("/tmp/foo.txt", "w")

f.write("Pythonは非常に優れた言語だ。\ nはい、確かに非常に優れている!! \ n" )

# 開いているファイルを閉じる

f.close()
  • 最初のパラメータは、開くファイルの名前です。
  • 2番目のパラメータは、ファイルで使用される文字を記述します。 ファイルが読み取り専用の場合、モードは「r」、「w」は書き込みのみに使用され(同じ名前のファイルがある場合は削除されます)、「a」はファイルの内容を追加するために使用されます。 書き込まれたデータはすべて自動的に末尾に追加されます。「r +」は読み取りと書き込みを同時に行うために使用されます。 modeパラメータはオプションです。「r」がデフォルト値になります。

この時点でファイルfoo.txtを開きます。表示は次のとおりです。

$ cat /tmp/foo.txt 
Pythonは非常に優れた言語だ。
はい、確かに非常に優れている。

ファイルオブジェクトメソッド

このセクションの残りの例では、fというファイルオブジェクトが作成されていることを前提としています。

f.read()

ファイルの内容を読み取るには、f.read(size)を呼び出します。これにより、一定量のデータが読み取られ、文字列またはバイトオブジェクトとして返されます。

sizeは選択可能の数値型パラメータです。 サイズが無視されるか負の場合、ファイルのすべての内容が読み取られて返されます。

次の例では、ファイルfoo.txtがすでに存在している(上記の例で作成されている)ことを前提としています。

実例

#!/usr/bin/python3

# ファイルを開く
f = open("/tmp/foo.txt", "r")

str = f.read()
print(str)

# 開いているファイルを閉じる
f.close()

上記のプログラムを実行すると、出力結果は次のようになります。

Pythonは非常に優れた言語だ。

はい、確かに非常に優れている。

f.readline()

f.readline()は、ファイルから1行を読み取ります。 改行記号は「\ n」です。 f.readline()が空の文字列を返す場合は、最後の行が読み取られたことを意味します。

実例

#!/usr/bin/python3

# ファイルを開く
f = open("/tmp/foo.txt", "r")

str = f.readline()
print(str)

# 開いているファイルを閉じる
f.close()

上記のプログラムを実行すると、出力結果は次のようになります。

Pythonは非常に優れた言語だ

f.readlines()

f.readlines()は、ファイルに含まれるすべての行を返します。

オプションのパラメータsizehintが設定されている場合、指定された長さのバイトが読み取られ、これらのバイトは行に分割されます。

実例

#!/usr/bin/python3

# ファイルを開く
f = open("/tmp/foo.txt", "r")

str = f.readlines()
print(str)

# 開いているファイルを閉じる
f.close()

上記のプログラムを実行すると、出力結果は次のようになります。

[‘Pythonは非常に優れた言語だ。\n’, ‘はい、本当に優れている!!\n’]

もう1つの方法は、ファイルオブジェクトを繰り返し処理してから、各行を読み取ることです。

実例

#!/usr/bin/python3

# ファイルを開く
f = open("/tmp/foo.txt", "r")

for line in f:
    print(line, end='')

# 開いているファイルを閉じる
f.close()

上記のプログラムを実行すると、出力結果は次のようになります。

Pythonは非常に優れた言語だ。
はい、確かに非常に優れている。

この方法は簡単ですが、適切な制御を提供していません。 2つの処理メカニズムは異なるため、それらを混合しないことをお勧めします。

f.write()

f.write(string)は文字列をファイルに書き込み、書き込まれた文字数を返します。

実例

#!/usr/bin/python3

# ファイルを開く
f = open("/tmp/foo.txt", "w")

num = f.write( " Pythonは非常に優れた言語だ。\nはい、確かに非常に優れている!!\n" )
print(num)
#開いているファイルを閉じる
f.close()

上記のプログラムを実行すると、出力結果は次のようになります。

29

文字列ではないものを書きたい場合は、最初にそれを変換する必要があります。

実例

#!/usr/bin/python3

# ファイルを開く
f = open("/tmp/foo1.txt", "w")

value = ('www.ceodata.com', 14)
s = str(value)
f.write(s)

# 開いているファイルを閉じる
f.close()

上記のプログラムを実行し、foo1.txtファイルを開きます。

$ cat /tmp/foo1.txt 
('www.ceodata.com', 14)

f.tell()

f.tell()は、ファイルオブジェクトの現在の位置を返します。これは、ファイルの先頭からのバイト数です。

f.seek()

ファイルの現在の位置を変更したい場合は、f.seek(offset、from_what)関数を使用してください。

from_whatの値は、0の場合は開始を意味し、1の場合は現在の位置を意味し、2はファイルの終わりを意味します。次に例を示します。

  • seek(x、0):開始位置、つまりファイルの最初の行の最初の文字からx個文字を移動することを意味します。
  • seek(x、1):x個文字を現在の位置から後方に移動することを意味します。
  • seek(-x、2):ファイルの終わりからx個文字を前に移動することを意味します。

from_what値はデフォルトで0であり、これはファイルの先頭です。 完全な例を以下に示しています。

>>> f = open('/tmp/foo.txt', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5)     # ファイルの6バイト目に移動する。
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # ファイルの最後から3番目のバイトに移動する。
13
>>> f.read(1)
b'd'

f.close()

テキストファイル(ファイルを開くモードでbがないファイル)では、ファイルの先頭を基準にしてのみ配置されます。

ファイルの処理が終了したら、f.close()を呼び出してファイルを閉じ、システムリソースを解放します。ファイルを再度呼び出そうとすると、例外がスローされます。

>>> f.close()
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: I/O operation on closed file

ファイルオブジェクトを扱うときは、withキーワードを使用するのが非常に良い方法です。 終了後、ファイルを正しく閉じるのに役立ちます。 そして、それはtry-finallyステートメントよりも短いです。

>>> with open('/tmp/foo.txt', 'r') as f:
...     read_data = f.read()
>>> f.closed
True

isatty()やtrucate()など、ファイルオブジェクトには他のメソッドもありますが、これらは通常あまり使用されません。

pickleモジュール

Pythonのpickleモジュールは、基本的なデータシリアル化と逆シリアル化を実装します。

pickleモジュールのシリアル化操作により、プログラムで実行されているオブジェクト情報をファイルに永続的に保存できます。

pickleモジュールの逆シリアル化操作により、ファイルから前回のプログラムで保存されたオブジェクトを作成できます。

基本的なインターフェース:

pickle.dump(obj、file、[、protocol])

pickleオブジェクトを使用すると、ファイルを開いて読み取ることができます。

x = pickle.load(file)

注:ファイルから文字列を読み取り、元のpythonオブジェクトに再構築します。

file:read()およびreadline()インターフェースを備えたファイルのようなオブジェクト。

実例1

#!/usr/bin/python3
import pickle

#pickleモジュールを使用してデータオブジェクトをファイルに保存する
data1 = {'a': [1, 2.0, 3, 4+6j],
         'b': ('string', u'Unicode string'),
         'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.
pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)

output.close()

実例2

#!/usr/bin/python3
import pprint, pickle

#pickleモジュールを使用してファイルからPythonオブジェクトを再構築する
pkl_file = open('data.pkl', 'rb')

data1 = pickle.load(pkl_file)
pprint.pprint(data1)

data2 = pickle.load(pkl_file)
pprint.pprint(data2)

pkl_file.close()
Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です