7。 入出力
プログラムの出力を表示する方法はいくつかあります。 データは、人間が読める形式で印刷することも、将来使用するためにファイルに書き込むこともできます。 この章では、いくつかの可能性について説明します。
7.1。 ファンシーな出力フォーマット
これまで、値を書き込む2つの方法に遭遇しました。式ステートメントと print()関数です。 (3番目の方法は、ファイルオブジェクトのwrite()
メソッドを使用することです。標準出力ファイルはsys.stdout
として参照できます。 詳細については、ライブラリリファレンスを参照してください。)
多くの場合、スペースで区切られた値を単に印刷するよりも、出力のフォーマットをより細かく制御する必要があります。 出力をフォーマットする方法は2つあります。 最初の方法は、すべての文字列処理を自分で行うことです。 文字列のスライスと連結操作を使用して、想像できる任意のレイアウトを作成できます。 文字列型には、特定の列幅に文字列をパディングするための便利な操作を実行するいくつかのメソッドがあります。 これらについては、まもなく説明します。 2番目の方法は、形式の文字列リテラル、または str.format()メソッドを使用することです。
string モジュールには、値を文字列に置き換えるさらに別の方法を提供する Template クラスが含まれています。
もちろん、1つの質問が残っています。値を文字列に変換するにはどうすればよいですか? 幸い、Pythonには任意の値を文字列に変換する方法があります。それを repr()または str()関数に渡します。
str()関数は、かなり人間が読める値の表現を返すことを目的としていますが、 repr()は、インタプリタが読み取ることができる表現を生成することを目的としています(または同等の構文がない場合は、 SyntaxError を強制します)。 人間が消費するための特定の表現を持たないオブジェクトの場合、 str()は repr()と同じ値を返します。 数値やリストや辞書などの構造などの多くの値は、どちらの関数を使用しても同じ表現になります。 特に、文字列には2つの異なる表現があります。
いくつかの例:
正方形と立方体のテーブルを作成する2つの方法は次のとおりです。
(最初の例では、 print()の動作方法により、各列の間に1つのスペースが追加されました。デフォルトでは、引数の間にスペースが追加されます。)
この例は、文字列オブジェクトの str.rjust()メソッドを示しています。このメソッドは、左側にスペースを埋めることで、指定された幅のフィールド内の文字列を右揃えにします。 同様のメソッド str.ljust()と str.center()があります。 これらのメソッドは何も書き込まず、新しい文字列を返すだけです。 入力文字列が長すぎる場合、切り捨てられませんが、変更されずに返されます。 これは列のレイアウトを台無しにしますが、通常は値について嘘をついている代替案よりも優れています。 (本当に切り捨てが必要な場合は、x.ljust(n)[:n]
のように、いつでもスライス操作を追加できます。)
別のメソッド str.zfill()があります。このメソッドは、左側の数値文字列にゼロを埋め込みます。 プラス記号とマイナス記号について理解します。
str.format()メソッドの基本的な使用法は次のようになります。
角かっことその中の文字(フォーマットフィールドと呼ばれる)は、 str.format()メソッドに渡されるオブジェクトに置き換えられます。 括弧内の数字は、 str.format()メソッドに渡されるオブジェクトの位置を示すために使用できます。
str.format()メソッドでキーワード引数が使用されている場合、それらの値は引数の名前を使用して参照されます。
位置引数とキーワード引数は任意に組み合わせることができます。
'!a'
( ascii()を適用)、'!s'
( str()を適用)および'!r'
( reprを適用())は、フォーマットされる前に値を変換するために使用できます。
オプションの':'
およびフォーマット指定子は、フィールド名の後に続けることができます。 これにより、値のフォーマット方法をより細かく制御できます。 次の例では、円周率を小数点以下3桁に丸めます。
':'
の後に整数を渡すと、そのフィールドの幅は最小文字数になります。 これは、テーブルをきれいにするのに役立ちます。
分割したくない非常に長いフォーマット文字列がある場合は、位置ではなく名前でフォーマットする変数を参照できると便利です。 これは、dictを渡し、角かっこ'[]'
を使用してキーにアクセスするだけで実行できます。
これは、テーブルを「**」表記のキーワード引数として渡すことによっても実行できます。
これは、すべてのローカル変数を含む辞書を返す組み込み関数 vars()と組み合わせると特に便利です。
str.format()を使用した文字列フォーマットの完全な概要については、フォーマット文字列構文を参照してください。
7.1.1。 古い文字列のフォーマット
%
演算子は、文字列のフォーマットにも使用できます。 左の引数をsprintf()
スタイルのフォーマット文字列のように解釈して右の引数に適用し、このフォーマット操作の結果の文字列を返します。 例えば:
詳細については、 printfスタイルの文字列フォーマットセクションを参照してください。
7.2。 ファイルの読み取りと書き込み
open()はファイルオブジェクトを返し、最も一般的にはopen(filename, mode)
の2つの引数で使用されます。
最初の引数は、ファイル名を含む文字列です。 2番目の引数は、ファイルの使用方法を説明するいくつかの文字を含む別の文字列です。 モードは、ファイルの読み取りのみの場合は'r'
、書き込みのみの場合は'w'
(同じ名前の既存のファイルは消去されます)、 [ X153X]は、追加するファイルを開きます。 ファイルに書き込まれたデータはすべて自動的に最後に追加されます。 'r+'
は、読み取りと書き込みの両方でファイルを開きます。 mode 引数はオプションです。 'r'
は、省略した場合に想定されます。
通常、ファイルはテキストモードで開かれます。つまり、特定のエンコーディングでエンコードされた文字列をファイルとの間で読み書きします。 エンコーディングが指定されていない場合、デフォルトはプラットフォームに依存します( open()を参照)。 モードに追加された'b'
は、ファイルをバイナリモードで開きます。これで、データはバイトオブジェクトの形式で読み書きされます。 このモードは、テキストを含まないすべてのファイルに使用する必要があります。
テキストモードでは、読み取り時のデフォルトは、プラットフォーム固有の行末(Unixでは\n
、Windowsでは\r\n
)を\n
に変換することです。 テキストモードで書き込む場合、デフォルトでは、\n
の出現箇所がプラットフォーム固有の行末に変換されます。 このファイルデータの舞台裏での変更はテキストファイルには問題ありませんが、JPEG
またはEXE
ファイルのようなバイナリデータは破損します。 このようなファイルの読み取りと書き込みを行うときは、バイナリモードの使用に十分注意してください。
ファイルオブジェクトを処理するときは、 with キーワードを使用することをお勧めします。 利点は、ある時点で例外が発生した場合でも、スイートの終了後にファイルが適切に閉じられることです。 との使用は、同等の try -最終的にブロックを書き込むよりもはるかに短くなります。
with キーワードを使用していない場合は、f.close()
を呼び出してファイルを閉じ、ファイルで使用されているシステムリソースをすぐに解放する必要があります。 ファイルを明示的に閉じない場合、Pythonのガベージコレクターは最終的にオブジェクトを破棄し、開いているファイルを閉じますが、ファイルはしばらく開いたままになる可能性があります。 別のリスクは、異なるPython実装が異なる時間にこのクリーンアップを実行することです。
with ステートメントまたはf.close()
の呼び出しによってファイルオブジェクトが閉じられた後、ファイルオブジェクトの使用は自動的に失敗します。
7.2.1。 ファイルオブジェクトのメソッド
このセクションの残りの例では、f
というファイルオブジェクトがすでに作成されていることを前提としています。
ファイルの内容を読み取るには、f.read(size)
を呼び出します。これにより、ある量のデータが読み取られ、文字列(テキストモードの場合)またはバイトオブジェクト(バイナリモードの場合)として返されます。 size はオプションの数値引数です。 size が省略されているか負の場合、ファイルの内容全体が読み取られて返されます。 ファイルがマシンのメモリの2倍の大きさである場合、それはあなたの問題です。 それ以外の場合は、最大で size バイトが読み取られて返されます。 ファイルの終わりに達した場合、f.read()
は空の文字列()を返します。
f.readline()
はファイルから1行を読み取ります。 改行文字(\n
)は文字列の最後に残され、ファイルが改行で終わっていない場合にのみファイルの最後の行で省略されます。 これにより、戻り値が明確になります。 f.readline()
が空の文字列を返す場合、ファイルの終わりに到達していますが、空白行は'\n'
で表され、文字列には改行が1つだけ含まれています。
ファイルから行を読み取る場合は、ファイルオブジェクトをループできます。 これはメモリ効率が高く、高速で、単純なコードにつながります。
リスト内のファイルのすべての行を読み取りたい場合は、list(f)
またはf.readlines()
を使用することもできます。
f.write(string)
は、 string の内容をファイルに書き込み、書き込まれた文字数を返します。
他のタイプのオブジェクトは、書き込む前に、文字列(テキストモード)またはバイトオブジェクト(バイナリモード)のいずれかに変換する必要があります。
f.tell()
は、ファイル内のファイルオブジェクトの現在の位置を示す整数を返します。これは、バイナリモードの場合はファイルの先頭からのバイト数で表され、テキストモードの場合は不透明な数値で表されます。
ファイルオブジェクトの位置を変更するには、f.seek(offset, from_what)
を使用します。 位置は、オフセットを基準点に追加して計算されます。 基準点は、 from_what 引数によって選択されます。 from_what の値0はファイルの先頭から測定し、1は現在のファイル位置を使用し、2はファイルの末尾を参照ポイントとして使用します。 from_what は省略可能で、デフォルトは0で、ファイルの先頭を参照ポイントとして使用します。
テキストファイル(モード文字列でb
なしで開かれたファイル)では、ファイルの先頭を基準にしたシークのみが許可されます(seek(0, 2)
でファイルの最後をシークする場合を除く)。有効なオフセット値は、f.tell()
から返される値、つまりゼロのみです。 その他の offset 値は、未定義の動作を生成します。
ファイルオブジェクトには、isatty()
やtruncate()
など、あまり使用されない追加のメソッドがいくつかあります。 ファイルオブジェクトの完全なガイドについては、ライブラリリファレンスを参照してください。
7.2.2。 構造化データの保存 json
文字列は、ファイルへの書き込みとファイルからの読み取りが簡単にできます。 read()
メソッドは文字列のみを返すため、数値にはもう少し手間がかかります。文字列は、'123'
のような文字列を受け取る int()のような関数に渡す必要があります。 ]そしてその数値123を返します。 ネストされたリストや辞書など、より複雑なデータ型を保存する場合、手動での解析とシリアル化は複雑になります。
Pythonでは、複雑なデータ型をファイルに保存するためのコードを常に作成およびデバッグするのではなく、 JSON(JavaScript Object Notation)と呼ばれる一般的なデータ交換形式を使用できます。 json と呼ばれる標準モジュールは、Pythonデータ階層を取得し、それらを文字列表現に変換できます。 このプロセスはシリアル化と呼ばれます。 文字列表現からデータを再構築することを逆シリアル化と呼びます。 シリアル化と逆シリアル化の間に、オブジェクトを表す文字列がファイルまたはデータに保存されているか、ネットワーク接続を介して離れたマシンに送信されている可能性があります。
ノート
JSON形式は、データ交換を可能にするために最近のアプリケーションで一般的に使用されています。 多くのプログラマーはすでにこれに精通しているため、相互運用性に適しています。
オブジェクトx
がある場合は、次の簡単なコード行でそのJSON文字列表現を表示できます。
dumps()関数の別の変形である dump()は、オブジェクトをテキストファイルにシリアル化するだけです。 したがって、f
が書き込み用に開かれたテキストファイルオブジェクトである場合、次のことができます。
オブジェクトを再度デコードするには、f
が読み取り用に開かれたテキストファイルオブジェクトの場合:
この単純なシリアル化手法ではリストと辞書を処理できますが、JSONで任意のクラスインスタンスをシリアル化するには、少し余分な労力が必要です。 json モジュールのリファレンスには、この説明が含まれています。