Python3追加ライブラリで個人的に捗っている標準ライブラリをピックアップしてみた

Python3以降に追加された標準ライブラリで、個人的に捗ったものを中心にピックアップしてみました。
2019.06.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

たまたま次の記事を見て、Python3への移行は元号みたいにスパッとはいかないものだなと感じています。

単純なコーディングを除くと、移行で意外とハマるのが標準ライブラリです。Py2の知識が軽く上書きされる感じになります。今回はPython2とPython3で標準ライブラリを比較してみて、Python3側に追加されていて且つ個人的に捗るものをピックアップしつつ触ってみました。

参考ページ

以下の公式ドキュメントを元にしています。

例外系

RecursionError

再帰処理の回数を超えると発行されます。

一応、以下のようなコードで対処も可能です。

import sys
sys.setrecursionlimit(2000)

OSError

以下のように継承クラスが増えました。単純なExceptionで済ませていた場合は、より動作に沿ったクラスを使うべきでしょう。

  • FileNotFoundError
  • FileExistsError
  • TimeoutError

正規表現

re.fullmatch

Python2ではre.matchによる先頭一致のみでしたが、Python3ではそれに加えてre.fullmatchによる全体一致が使えます。

import re
pattern = re.compile("Dev(?P<parts>.+)")
pattern.fullmatch("Developers.IO").group('parts')

> 'elopers.IO'

ファイル・ディレクトリ操作

Python2とPython3でがらっと変わった感じのある領域です。

pathlib

Python2でos.pathを使っていたシーンは、Python3ではpathlib.Pathを使うことでより可視性が上がると思います

os.path

import os

# 存在確認
os.path.exists('/path/to')
# 親ディレクトリ
os.path.dirname('/path/to')
# 絶対パス
os.path.abspath('/path/to')

pathlib.Path

import pathlib

path = pathlib.Path('/path/to')
# 存在確認
path.exists()
# 親ディレクトリ
path.parent
# 絶対パス
path.resolve()

より詳細な比較については、以下のリンク先から確認してみてください。

os モジュールにあるツールとの対応付け — Python 3.7.4rc1 ドキュメント

tempfile.TemporaryDirectory

Python2では削除前提の一時ディレクトリが必要だった場合に色々と手間がかかっていましたが、Python3ではtempfile.TemporaryDirectoryを使うことで安全に操作することが出来ます。

import tempfile
import pathlib

with tempfile.TemporaryDirectory() as tempdir:
    print(tempdir)
    path = pathlib.Path(tempdir, 'test.txt')
    print(str(path))
> /var/folders/pw/281km8lx4wn21ryf4y4v74h80000gq/T/tmpkc_meyx0
> /var/folders/pw/281km8lx4wn21ryf4y4v74h80000gq/T/tmpkc_meyx0/test.txt

テスト

unittest.mock

クラスをモックに置き換えて、実際に関数が使われているかどうかを確認することが出来ます。

以下の処理は、patchにてPathをmockに置き換え、call_countにてexistsの呼び出し回数をチェックしています。1回呼び出した状態でそれが正しくないとしたことで、AssertionErrorが発生しています

from unittest.mock import patch, MagicMock
import pathlib

test_mock = MagicMock()
with patch('pathlib.Path', return_value=test_mock):
     pathlib.Path('localhost').exists()
     assert test_mock.exists.call_count != 1
> <MagicMock name='mock.exists()' id='4507735600'>
> Traceback (most recent call last):
>   File "<stdin>", line 3, in <module>
>   AssertionError

まとめ

Python3で捗りそうなことが伝わって、Python2からの移行の後押しになれば幸いです。