【Python】 Python ~ 基本編 / ファイル読込・書込 ~

■ はじめに

Python の ファイルの扱い方を学ぶ

目次

【1】読み込み
 1)read()
 2)readlines()
【2】書き込み
 1)write()
  [補足] 書き込みモード
【3】with ブロック
【4】日本語(UTF-8)対応
【5】サンプル
 例1:read() / with
 例2:readlines() / with
 例3:write() / with
 例4:UTF-8 (codecs) の write / read
 例5:リストをファイル化
 例6:ファイルをリストとして読み込む
 例7:行の中身を抽出/排除

【1】読み込み

1)read()

ファイル全体を文字列として読み込む

2)readlines()

 1行ごとに読み込む

【2】書き込み

1)write()

文字列を書き込み

[補足] 書き込みモード

1)mode='w’:上書きで書き込む
2)mode='a’:追加で書き込む

【3】with ブロック

* 終了時に自動的にクローズされる
 => C# の using , java の try-with-resources みたいなもん

with open('hello.txt') as file:
   text = file.read()

補足:Context Managers(コンテキストマネージャ)

with 文に関連して、コンテキストマネージャってのがある。
長くなったので、以下の関連記事を参照のこと

Python ~ 基本編 / クラス・継承 ~
https://dk521123.hatenablog.com/entry/2019/08/29/220537

【4】日本語(UTF-8)対応

codecs を使う

import codecs

with codecs.open('japanese.txt', 'r', 'utf-8') as file:
   text = file.read()

【5】サンプル

例1:read() / with

def main():
    with open('hello.txt') as file:
        text = file.read()
        print(text)

if __name__ == '__main__':
    main()

hello.txt

Hello
World!!
Tom

出力結果

Hello
World!!
Tom

例2:readlines() / with

import os

output_file = 'hello_out.dot'
# あったら削除
if(os.path.isfile(output_file)):
  os.remove(output_file)

remove_tables = {'table3', 'table4'}
def can_find(lines):
  for remove_table in remove_tables:
    if (remove_table in lines):
      return True
  return False

with open('hello.dot', 'r', encoding='utf-8') as file:
  line_number = 1
  lines = file.readline()
  while lines:
    print(f'{line_number} - {lines}')
    if (can_find(lines)):
      print(f"Found, Skip!!! {lines}")
    else:
      # 追記モード
      with open(output_file, mode='a') as out_file:
        out_file.write(lines)
    line_number = line_number + 1
    lines = file.readline()

hello.dot

digraph {
    ranksep=0.3;
    nodesep=0.7;
    rankdir="TB"
    {rank = source; table1;}
    table1-> table2;
    table2 -> table3;
    table4 -> table2;
    table2 -> table5;
}

hello_out.dot

digraph {
    ranksep=0.3;
    nodesep=0.7;
    rankdir="TB"
    {rank = source; table1;}
    table1-> table2;
    table2 -> table5;
}

例3:write() / with

def main():
    hello = 'hello world, Mike!!'
    with open('hello_out.txt', mode='w') as file:
        file.write(hello)

if __name__ == '__main__':
    main()

例4:UTF-8 (codecs) の write / read

import codecs

def main():
  hello = 'こんにちは、世界!'
  with codecs.open('japanese.txt', 'w', 'utf-8') as file:
    file.write(hello)

  with codecs.open('japanese.txt', 'r', 'utf-8') as file:
    text = file.read()
    print('Result : ' + text)

if __name__ == '__main__':
    main()

出力結果

Result : こんにちは、世界!

例5:リストをファイル化

list = ['Mike', 'Tom', 'Sam']
with open('list.txt', 'w') as file:
  for line in list:
    file.write(f'{line}\n')

例6:ファイルをリストとして読み込む

with open("hello.txt", "r", encoding="utf-8") as file:
  list = file.read().splitlines()
  print(list)

https://stackoverflow.com/questions/15233340/getting-rid-of-n-when-using-readlines
hello.txt

Mike
Tom
Sam
Kevin

出力結果例

['Mike', 'Tom', 'Sam', 'Kevin']

例7:行の中身を抽出/排除

path = 'demo.dot'

with open(path) as file:
  lines = file.read().splitlines()

# 抽出 (in)
list = [line for line in lines if 'table3' in line]
print(list)

print('*******************')

# 除外(not in)
list = [line for line in lines if 'table3' not in line]
print(list)

demo.dot

digraph {
    graph [rankdir=LR]
    node [fontname="MS Gothic"]
    table1
    table2
    table3
    table4
    table1 -> table2
    table2 -> table3
    table2 -> table4
}

出力結果例

['\ttable3', '\ttable2 -> table3']
*******************
['digraph {', '\tgraph [rankdir=LR]', '\tnode [fontname="MS Gothic"]', '\ttable1', '\ttable2', '\ttable4', '\ttable1 -> table2', '\ttable2 -> table4', '}']

参考文献

https://yukun.info/python-file/
withブロック
https://note.nkmk.me/python-file-io-open-with/
codecs
https://qiita.com/kanemu/items/1080972679c9cb70ebff

関連記事

Python ~ 基本編 / 文字列 ~
https://dk521123.hatenablog.com/entry/2019/10/12/075251
Python ~ 基本編 / JSON
https://dk521123.hatenablog.com/entry/2019/10/12/075251
Python ~ 基本編 / クラス・継承 ~
https://dk521123.hatenablog.com/entry/2019/08/29/220537
Python ~ 基本編 / パス情報抽出 ~
https://dk521123.hatenablog.com/entry/2022/02/23/000000
Pythonでの文字コード関連のトラブルシューティング
https://dk521123.hatenablog.com/entry/2020/06/19/121139