Remrinのpython攻略日記

python3に入門しました。python3についてあれこれとサンプルコードとか。

pythonでファイルの読み書き

pythonでファイルの読み書きです。
 
python3で外部ファイルを開くときはcodecsモジュールは不要です。
 
パスが通ったディレクトリにhyaku.txtがあることを前提にしています。
なければ、メモ帳などで適当に複数行の文字を書き込んだりで。
今回は百人一首を書き込んだテキストファイルを準備しました。 

# coding: utf-8

#テキストファイルの読み込み
with open("hyaku.txt", "r") as f:  # txt形式の読み込み
    data = f.read()                # ひとまとまりのデータとして読み込む
 
data = data.split("\n")            # 改行コードで1行ずつに分割
print(data)                        # 'あきのたの... と100行分表示
print(len(data))                   # 100
 
#テキストファイルへの書き込み(上書き)
text = "\n".join(data)             # 改行コードでつなぐ
with open("hyaku.txt", "w") as f:  # w:上書きモード
    f.write(text)                  # 書き込めるのは文字列型のみ

 
○open → 読み(書き) → closeとしたり、try/catchする方法もあるが、
 途中の記述で予期せぬエラーが出た場合のため、
 自動的にファイルを閉じるwith asの書き方を推奨。
 
○file()オブジェクト[built-in] のモード

"r" 読み込み(デフォ)
"w" 書き出し
"x" 新規作成して書き込み用に開く。すでに存在すれば失敗
"a" 書き込み用に開き、既に存在するファイルなら末尾に追加
"b", "t" "t":テキストモード(デフォ)、"b":バイナリモード
+ 書き込みと読み出しの両方を可能にする。

 

ファイルの読み込み方

(1)f.read() 全行一括読み込み
    ・f.read(100)などとして、100文字ずつ取り出せる。
    ・イテレートすると1文字ずつ取り出す。
    ・1行ごとイテレートする場合は、split("\n")してから。

with open("hyaku.txt", "r") as f:
    data = f.read(100) # 1つながりのstr型として最初の100文字を読み込む    
for i in data:         # str型をイテレータにすると、1文字ずつ取り出す
    print(i)
# あ
# き
# の
# た
# の
# ...

 
(2)f.readlines() 全行を読み込み、行ごとのリストを取得。
    ・改行コードは実行されずに、文字として(\n)を含んだまま。
    ・イテレートすると1行ずつになる。

with open("hyaku.txt", "r") as f:
    lines = f.readlines()
    print(lines) #改行コードを含んだままのstr型のリスト
['あきのたの かりほのいほの とまをあらみ わがころもでは つゆにぬれつつ\n', 'はるすぎて...

 

(3)f.readline() 1行ずつ読み込む。文末の改行コードが実行、つまり改行される。

with open("hyaku.txt", "r") as f:
    line = f.readline()
    while line:
        print(line)
        line = f.readline()

 
(4)ファイルオブジェクトのままイテレートすると、1行ずつになる。
    ・文末の改行コード(\n)は実行、つまり改行される。

with open("hyaku.txt", "r") as f:
    for line in f:
        print(line, end="")      #改行がかぶらないように、endオプションを指定する
# あきのたの かりほのいほの とまをあらみ わがころもでは つゆにぬれつつ
# はるすぎて なつきにけらし しろたへの ころもほすてふ あまのかぐやま
# ... 

 
(5)ファイルの最初の5行を表示する。

print("".join([line for n, line in enumerate(
        open("data/test1.txt", encoding="utf-8")) if n < 5]))

 
[読み込みtips]
・読み込むファイルには空白行が混じっていることもあるので削除。
・文末の改行\n消し。
・タブ(\t)やカンマ、半角スペース区切りを利用して .split("\t")など
・空のリストなどを準備してappendしていく。
・読み込みデータが1行に2つずつなら、この後dict()で辞書型にしたりもできる。
 
○ファイルの探索順序
1.実行中のファイルのあるフォルダ
2.カレントフォルダ
3.環境変数「PYTHONPATH」に列挙したフォルダ
4.sys.pathに登録してあるフォルダ
5 パスの通ったフォルダ内に/Users/ユーザ名/~で始まるパスを記入した.pthファイルを置く。
(例) site-package内にmymodulesというフォルダを置く。
site-package内にmymodules.pthというファイルを置き、中にパス名を記述。
 

ファイルの書き込み

文字列を1つ準備し、ファイルに書き込む

string = "test string"
with open("test.txt", "w", encoding="utf-8") as f:
    f.write(string)

 
文字列のシーケンスを準備して、ファイルに書き込む。
改行コードは付加されない。

strings = ["test",  "string", "No.2"]
with open("test.txt", "w", encoding="utf-8") as f:
    f.writelines(strings)
# txtファイルの内容:teststringNo.2

 
改行コードを付けたいときは、"\n".join()など

strings = ["test",  "string", "No.2"]
with open("test.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(strings))
# txtファイルの内容:
# test
# string
# No.2

 
python用のデータ保存にはpickleライブラリも使えます。
 

バイナリファイルを扱う。

テキスト形式以外のファイルはすべてバイナリファイルとなります。
bytes型のオブジェクトとして読み取るので、比較などは「b"..."」などバイト文字列として扱う。
bytes型についてはこちらを参照

with open("data/img01.png", "rb") as imgfile:
    imgsrc = imgfile.read()
    print(type(imgsrc))             # <class 'bytes'>
    if imgsrc[1:4] == b"PNG":
        print("pngファイルです")
    else:
        print("pngファイルではありません")
# pngファイルです

 

システムのエンコードの確認

import sys
print(sys.getfilesystemencoding())
# mbcs

MBCS: Multibyte Character Set
マルチバイト:1バイト文字や2バイト文字が混在すること。