
ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第4回 「ファイル操作とAPI」学習メモ
はじめに
ノンプロ研で開催されている、「中級プログラミング講座【Pythonコース】」第1期 第4回の講座の内容と、学習したことなどを、講座の回毎にまとめていきます。
第4回のアジェンダは、「ファイル操作とAPI」です。
1.pathlibモジュール
pathlibモジュール

pathlibモジュールは、ファイル・フォルダ(ディレクトリ)を操作する組み込みモジュールです。
pathlibモジュールは、Python3.4から追加になりました。
pathlibモジュールのクラス

pathlibモジュールの特徴として、Pathクラスを使って、ファイル・フォルダ(ディレクトリ)を操作する処理を、オブジェクトとして操作できるという特徴があります。
Pathクラスのインポート

モジュールのインポートの仕方のうち、モジュールから直接インポートする方法でインポートしています。
モジュールのインポートについては、前回の講座で学習しています。詳細は、下記ご参照ください。
Pathオブジェクトのコンストラクタ

コンストラクタのパラメータには、パスを表す文字列を指定することができます。
パスの指定の仕方も、相対パス、絶対パスだけではなく、複数の指定の仕方があります。
演習で、Pathオブジェクトのコンストラクタの指定の仕方について確認していきます。
from pathlib import Path
p = Path('04/folder/file.py') # ファイルの相対パス
print(p)
print(Path('04', 'folder', 'file.py')) # 部分パスの列挙
print(Path(p))
p_dir = Path('04/folder') # フォルダの相対パス
print(p_dir)
print(Path(p_dir / 'file.py')) # 演算子/で結合

戻り値は、Pathオブジェクトになります。
実行するOSがWindowsの場合、WindowsPathクラスのオブジェクト、Mac、Linuxの場合、PosixPathクラスのオブジェクトが返ります。
Pathクラスの属性①

cwdメソッドは、クラソメソッドなので、インスタンス生成を行わずに、メソッドを実行することができます。
ちなみに、cwdは、current working directoryの略で、現在の作業ディレクトリを取得するメソッドです。
cwd以外は、インスタンス属性、メソッドとなります。
また、メソッドは、単体で実行することも、つなげて実行することも可能です。
from pathlib import Path
p = Path('04/folder/file.py')
p_abs = p.resolve()
print(p_abs.relative_to(p_cwd))
print(p.resolve().relative_to(p_cwd))
最後の2行は、同じ結果が返ります。

Pathクラスの属性②

Pathオブジェクトが表すフォルダ(ディレクトリ)配下にあるファイル一覧の取得には、iterdirメソッドを使用します。
戻り値は、Pathオブジェクトの一覧のジェネレータが返ります。
ジェネレータとは、リストやタプルのように、for文で利用できるイテラブルなオブジェクトです。
ジェネレータはメモリ節約のための仕組みで、求められたときにだけ要素を生成して返します。
また、globメソッドは、Pathオブジェクトが表すフォルダ(ディレクトリ)内をパターンにマッチするファイルを検索し、対象フォルダ(ディレクトリ)配下のフォルダ(ディレクトリ)内のファイルもすべて一覧を取得することができます。
このglobメソッドと同様の処理を行うことができるモジュールに、globモジュールがあります。
しかし、pathlibモジュールを使用することで、複数モジュールのインポートをする必要が無いので、pathlibモジュールを使用したほうがコードはシンプルになります。
おまけ:os.pathモジュール
pathlibモジュール以外にも、ファイル・フォルダ(ディレクトリ)を操作するモジュールとして、os.pathモジュールがあります。
os.pathモジュールは、機能が多く、書き方が複雑なので、コードが凡長になりがちです。
pathlibモジュールを使用したほうが、シンプルなコードが書けるようになります。
なお、公式ドキュメントに、pathlibとos.pathのメソッドの対応表がありますので、差分確認することができます。
2.ファイルオブジェクト

ファイルを開いたり、読み込み・書き込みをしたり、閉じるなど、ファイルを操作する処理は、多くの場合、各ライブラリで提供されています。
しかし、すべての場合においてライブラリが提供されているわけではありません。
そのような場合、組み込み型のファイルオブジェクトを使用することになります。
open関数

open関数は、ファイルを開き、対応するファイルオブジェクトを返す関数です。
ファイルが開けない場合、例外OSErrorを送出します。
open関数のモード

ファイルの開き方による挙動は、下記のようになります。
’w’…既存ファイルを開いて書き込みを行うと、上書き(前の内容は消去されて最初から書き込み)
'x'…既存ファイルを開くと、失敗。
これ以外に、’+’があり、更新用として使用します。ファイルの開き方の指定である、'r’、’w’、'a’と一緒に指定します。
'r+'を指定すると、読み込み書き込みの両方ができます。書き込み時には、先頭から上書きされます。

add_line = '''
3,ベーグル,300,2'''
f = open('04/food.csv', 'r+', encoding='utf-8')
f.write(add_line)
f.close()
f = open('04/food.csv', 'r', encoding='utf-8')
print(f.read())
f.close()


'w+'を指定すると、'r+'同様読み込み書き込みの両方ができます。しかし、書き込み時には、'w'と同様、前の内容は消去されて最初から書き込みされます。

add_line = '''
3,ベーグル,300,2'''
f = open('04/food.csv', 'w+', encoding='utf-8')
f.write(add_line)
f.close()
f = open('04/food.csv', 'r', encoding='utf-8')
print(f.read())
f.close()


'a+'を指定すると、読み込み書き込みの両方ができます。追加書き込みができていますが、'a'のみを指定した際と差分が分かりませんでした…

add_line = '''
3,ベーグル,300,2'''
f = open('04/food.csv', 'a+', encoding='utf-8')
f.write(add_line)
f.close()
f = open('04/food.csv', 'r', encoding='utf-8')
print(f.read())
f.close()


open関数の文字コード

encodingオプションは、ファイルがテキストファイルの場合に有効です。
文字コードのデフォルトは、実行環境に依存します。
なお、現在の実行環境のエンコードは、localeモジュールのgetencoding()メソッドの戻り値で取得することができます。
open関数のnewline
公式ドキュメントには、「ストリームから受け取った改行文字をどのようにパースするかを決定」し、None, '', '\n', '\r', または '\r\n' のいずれかを指定することができるとあります。
ファイル読み込み時にはまった場合の参考サイト教えていただきました。
Pathクラスのopenメソッド

Pathクラスのopenメソッドは、組み込み関数openと同様の処理が可能です。
ファイルオブジェクトの属性

この属性は、すべてメソッドです。これ以外にも、ファイルオブジェクトが持つ属性はあります。
ファイルオブジェクトの操作の流れ

ファイルオブジェクトは、操作が終了したら閉じることが推奨されています。
closeしないことで起こる弊害としては、ファイルオブジェクトが異常終了した際に、書き込んだ内容が無くなることや、反映されないことなどがあります。
バイナリデータとは

テキストではないデータを、バイナリデータと言います。
with文
ファイル操作中は、なんらかの事象で処理が中断してしまうこともあります。
そんなときも確実に、ファイルオブジェクトを閉じて処理を終わりたい…そんな時に使用したいのが、with文です。
with文とは、事前に定義されたクリーンアップ処理を利用する場合に使用する構文です。定義済みのクリーンアップ処理は、ブロックを抜ける直前に実行されます。
このwith文に対応しているオブジェクトは、コンテキストマネージャと呼ばれます。
with文とファイルオブジェクト

with文を使用することで、closeメソッドを呼び出さなくても、ファイルオブジェクトを自動的に閉じる処理が実行されるようになり、かつコードが読みやすくなります。
積極的に使っていきましょう。
3.JSON
JSONとは

JSONは、テキストベースで、軽量なデータ交換を行うためのフォーマットです。そして、データ構造がシンプルであるため、人が目で見てわかりやすいことが特徴です。
APIから取得するデータが、JSON形式ということが多く、使用頻度が高いデータ形式です。
jsonモジュールとインポート

jsonモジュールは標準ライブラリのため、インストールは不要です。
importを行うことで、使用することができます。

jsonモジュールの関数

dumps, dump関数は、辞書→JSONへ変換(書き込み)、loads, load関数は、JSON→辞書へ変換(読み込み)を行う関数です。
dumps関数

辞書型のデータをJSON形式の文字列に変換することを、公式ドキュメントでは、エンコーディングと表現しています。
パラメータのうち、ensure_ascii=Falseとすることで、日本語がそのまま出力できるようになります。ensure_asciiパラメータのデフォルトはTrueです。
loads関数

JSON形式の文字列を辞書を変換することを、公式ドキュメントでは、デコーディングと表現しています。
4.API
APIとは

APIとは、ソフトウェア、プログラムとサービスをつなぐインターフェースのことを指します。
Web APIとは

Webの仕組みである、HTTP通信を使ったAPIのことを、Web APIと呼びます。
Web APIの公開によって、外部サービスと連携が生まれ、そこから、サービス、ビジネスが発展していくことは「APIエコノミー」と呼ばれ、使用する側、使用される側とも、ビジネスチャンスが広がるといわれています。
requestsモジュールとインポート

requestsモジュールは、標準ライブラリに含まれていないため、インストールが必要です。
Anaconda使用する場合、Anacondaに同梱されているため、インストールは不要です。

使用する場合は、インポートが必要です。
GETリクエストをしてレスポンスを受け取る

getメソッドのパラメータとして、URLを渡すことで、サーバーにリクエストを送信し、レスポンスを受け取ることができます。
Responseオブジェクト

getメソッドの戻り値は、Responseオブジェクトです。
このResponseオブジェクトは、HTTPレスポンスを表すオブジェクトとなります。
この属性一覧のうち、raise_fo_statusはメソッドとなります。
郵便番号検索APIを使ってみよう
郵便番号APIを使用して、WebAPIを使ってみます。
検索したい郵便番号は、クエリ文字列(URLパラメータ)で指定します。
クエリ文字列とは、サーバーに情報を送るためにURLの末尾につけ足す文字列(変数)のことです。このURLの最後に、「?」をつけて、その後から「パラメーター=値」を設定することができます。
import requests
url = '<https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060>'
r = requests.get(url)
r.raise_for_status()
print(r.text)

レスポンスは、JSON形式で定義されています。

実際に返ってきたJSON文字列を辞書型に変換して取得する場合、レスポンスフィールドのJSON定義は、下記のようにアクセスすることができます。

次は、jsonモジュールのloads関数を使って、JSON文字列を辞書型に変換してみます。
obj = json.loads(r.text)
print('ステータスコード:', obj['status'])
result = obj['results'][0]
print('都道府県:', result['address1'])
print('市区町村名:', result['address2'])
print('町域名:', result['address3'])

講座ツイートまとめ
講座では、記憶定着化のため、アウトプットすることが推奨されています。受講された皆様方のツイートまとめは、下記よりご参照ください。
まとめ
今回は、ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第4回「ファイル操作とAPI」について、講座内容と学習のメモまとめました。
ノンプロ研 中級プログラミング講座【Pythonコース】第1期の講座、全4回以上となります。
目次
1.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第1回 「関数と式」学習メモ
2.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第2回 「オブジェクトとクラス」学習メモ