TOP
プログラミング独学コンテンツ一覧
Pythonのよく使う標準ライブラリ一覧と使い方の例 その5

Pythonのよく使う標準ライブラリ一覧と使い方の例 その5

最終更新日
前回コンテンツは下記リンクよりご覧ください。
Pythonのよく使う標準ライブラリ一覧と使い方の例 その4

unittestで単体テストをする

Pythonの組み込みのunittestモジュールはPyUnitとしても知られており、コードのテストケースを作成し実行するための堅牢で柔軟なツールです。これは他のいくつかの言語で普及しているxUnitアーキテクチャに触発されています。テストはソフトウェア開発において不可欠な要素であり、コードが期待通りに動作することを保証します。unittestを使えばほぼすべてのPythonの関数やメソッドに対してテストを書くことができます。
# 関数に対するシンプルな単体テスト
import unittest

def add_numbers(x, y):
    return x + y

class TestAddNumbers(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add_numbers(1, 2), 3)

if __name__ == "__main__":
    unittest.main()
unittestモジュールにはいくつかの便利な機能があります。テストケースはunittest.TestCaseをサブクラス化し、そのサブクラスでメソッドを定義することで作成されます。各メソッドは1つのテストを表し、TestCaseが提供する様々なassertメソッドを使用します。2つの値が同じかどうかをチェックするassertEqualのように満たすべき条件をチェックしなければなりません。setupteardownメソッドにより、テストが実行される固定された環境を持つことができます。
# 単体テストにおけるsetup, teardownの使用
class TestAddNumbers(unittest.TestCase):
    def setUp(self):
        self.x = 1
        self.y = 2

    def test_add(self):
        self.assertEqual(add_numbers(self.x, self.y), 3)

    def tearDown(self):
        pass

if __name__ == "__main__":
    unittest.main()
個々のテストを書くためのフレームワークを提供するだけでなくunittestにはテストを実行してレポートを提供できるテストランナーも含まれています。unittest.main()を呼び出すことで、テストランナーは現在のモジュールにあるすべてのテストメソッドを見つけ実行できます。Pythonのunittestライブラリを使えば、開発者は自分のコードの安定性と信頼性に自信を持つことができます。
# 複数の単体テストを実行
class TestAddNumbers(unittest.TestCase):
    def setUp(self):
        self.x = 1
        self.y = 2

    def test_add(self):
        self.assertEqual(add_numbers(self.x, self.y), 3)

    def test_add_negative(self):
        self.assertEqual(add_numbers(-self.x, -self.y), -3)

    def tearDown(self):
        pass

if __name__ == "__main__":
    unittest.main()
このスクリプトではtest_addtest_add_negativeという2つのテストケースが定義されています。unittest.main()関数はスクリプトからすべてのテストケースを収集し実行します。

traceで処理の追跡をする

PythonのtraceモジュールはPython文の実行を追跡できる非常に便利なツールです。特に複雑なアプリケーションでは、デバッグやコードの流れを理解するためによく使われます。このモジュールはトレース結果を生成するメカニズムを提供し、コードが特定のポイントに入ったとき、または出たときを記録します。これはプロジェクトにオンボードしたての新人にとって特に有用であり、アプリケーションの異なるコンポーネントがどのように相互作用するかについての洞察を提供できます。
traceモジュールはスクリプト内のすべてのステートメントの実行を記録するために使用されます。以下はtraceモジュールの使い方の簡単な例です。
import trace

tracer = trace.Trace(count=True, trace=True)
tracer.run('print("Hello, World!")')
results = tracer.results()
この例ではcount=Truetrace=Trueの2つの引数でtrace.Traceを呼び出しています。count引数は各関数の呼び出し回数のカウントを可能にし、trace引数はトレース機能をオンにします。run関数はトレースコンテキスト内で提供されたコードを実行するために使用され、その結果はresults関数を通じて利用可能です。

traceの機能

traceモジュールは基本的な機能に加えて、より高度な機能をいくつかサポートしています。例えば、トレースされた関数のフィルタリング、関数呼び出し回数のレポート作成、トレース結果の保存による後々の解析などです。trace.Traceignoredirsパラメータを指定すると、特定のディレクトリにある関数のトレースを無視できます。このようなレベルの制御によりtraceはPythonのコード実行に関する洞察を得るための強力なツールになります。
import trace

tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix], count=True)
tracer.run('print("Hello, World!")')
results = tracer.results()
traceは強力なツールですが、他のロギングと同様にトレースによるパフォーマンスへの影響に注意することが重要です(特に本番環境)。また、特に大規模で複雑なスクリプトの場合、トレース出力を生成するデータ量が多いため、トレース出力を理解するのに圧倒されることがあることを心に留めておいてください。traceはコード実行の一部としてではなく、学習やデバッグのツールとして使用するのがベストです。

venvで仮想環境を用意する

Pythonプログラミングの領域では、異なるプロジェクトで作業することはしばしば異なる依存関係を必要とすることを意味します。venvは他のプロジェクトやグローバルなPythonのインストールに干渉することなく、特定のバージョンのPythonパッケージをインストールできる隔離された仮想環境を作成するために使用されます。各仮想環境は基本的に自己完結型のPythonインストールとして動作し、パッケージ間の競合を回避できるためプロジェクトの一貫性を維持するのに役立ちます。
venvを使用する最初のステップは新しい仮想環境を作成することです。これはvenvコマンドの後に環境を作成するディレクトリの名前を付けて実行します。
python3 -m venv myenv
このコマンドはmyenvディレクトリが存在しない場合、新しいディレクトリを作成し、その中に必要なスクリプトとディレクトリをセットアップします。mオプションはPythonにvenvモジュールをスクリプトとして実行するように指示します。
仮想環境を作成したら、それを使用する前にactivate(有効化)する必要があります。仮想環境を有効にするとPATHが変更され、pythonコマンドが正しいバージョンで実行されるようになり、PythonセッションがグローバルなPythonのインストールから分離されます。仮想環境を有効にするには次のコマンドを使用します。
source myenv/bin/activate
仮想環境が起動するとこの隔離された空間内でPythonパッケージをインストールされ使用できます。例えばpipを使ってこの環境にのみパッケージをインストールできます。
pip install requests
終了したら仮想環境をdeactivate(解除)することを忘れないでください。これによりターミナルセッションはグローバルなPythonコンテキストに戻されます。
deactivate

sysでインタプリタ的にスクリプトを制御する

sysモジュールは、Pythonインタープリタが使用または維持するいくつかの変数やインタープリタと対話する関数へのアクセスを提供します。
sysモジュールの最も一般的な用途の1つは、Pythonスクリプト内のコマンドライン引数にアクセスすることです。コマンドラインからPythonスクリプトを実行する際、スクリプトへ直接追加の引数を渡すことができます。これらの引数はPythonのリストであるsys.argvに格納されます。
import sys

print("This is the name of the script: ", sys.argv[0])
print("Number of arguments: ", len(sys.argv))
print("The arguments are: " , str(sys.argv))
このスクリプトではsys.argv[0]がスクリプト自体の名前、sys.argv[1]以降がスクリプトに渡した引数です。
sysモジュールのもう1つの便利な機能としてexit関数があります。この関数を使うとPythonスクリプトが自然に終了する前に終了させることができます。例えば、ある条件が満たされなかった場合にスクリプトを終了させたい場合があります。
import sys

if not condition:
    sys.exit("exitしました")
この例では、条件がFalseと評価された場合、スクリプトは終了し指定されたメッセージが表示されます。
sysモジュールは、標準入力、出力、エラーストリーム、システム固有の設定情報、およびその他の有用なリソースへのアクセスも提供します。システムレベルのプログラミングを行うためのPythonのツールキットとして不可欠なものであり、このモジュールに慣れることはPythonをマスターするための良いステップとなります。

warningsで警告文を操作する

Pythonのwarningsモジュールは、必ずしもプログラムを停止させるわけではないが、重要な意味を持つ可能性がある変更についてプログラムの利用者に警告するための便利なツールです。例えば、非推奨の機能についての警告、軽微な不具合についての通知、プログラムの機能に影響を与える可能性のある将来予測可能な問題についての警告などです。
警告の一般的な使用例としてある機能や特徴が非推奨になる場合があります。例えば、ライブラリを開発しているときにある関数の名前を変更することにしたとします。しかし、古い関数名を使用している既存のコードをすべて壊したくはないことがあります。そのようなときにwarningsモジュールを使ってユーザーに変更を警告できます。
import warnings

def old_function():
    warnings.warn("old_function is deprecated, use new_function instead", DeprecationWarning)
この例では、old_functionが呼び出されるたびにこの関数は非推奨であり、代わりにnew_functionを使うべきであるという警告をユーザーに発します。
warnings.filterwarnings()関数で警告が発行されたときの動作を制御可能です。デフォルトではwarningssys.stderrに出力されますがこの動作を変更できます。例えば、すべての警告をエラーに変えるには次のようにします。
warnings.filterwarnings('error')
この場合、警告メッセージを表示するだけでなく警告が発行されるたびにPythonは停止して例外を発生させます。
warningsモジュールの使い方を知っておくことは他の人が使うようなソフトウェアを書く人にとって非常に重要です。プログラムを完全に停止させることなく、ソフトウェアの使用に影響する可能性のある問題についてユーザーとコミュニケーションを取ることができる方法です。このようなコミュニケーションは変更が絶えないソフトウェア開発の世界では不可欠であり、ユーザーに変更点を知らせておくことは将来的に多くのトラブルを回避できます。

tracebackでスタックトレースを調査する

Pythonのtracebackモジュールは開発者のための強力なツールです。Pythonプログラムのスタックトレースを抽出し、フォーマットし、出力する方法を提供します。基本的に、スタックトレースはプログラムがどのような流れである時点に至ったかを示す関数呼び出しのリストです。エラーに至った実行経路を示すため、エラーの理解や診断に役立ちます。
基本的な例として、意図的にゼロ除算のエラーを発生させる場合を考えてみましょう。tracebackはエラーに至った実行経路を示すものです。
def divide(a, b):
    return a / b

def main():
    divide(1, 0)

if __name__ == "__main__":
    main()
このスクリプトを実行すると、PythonはZeroDivisionErrorを投げ、コンソールにトレースバックを表示します。エラーを処理して独自のトレースバックを表示したい場合はtracebackモジュールの出番です。
import traceback

def divide(a, b):
    try:
        return a / b
    except Exception:
        print("An error occurred!")
        traceback.print_exc()

def main():
    divide(1, 0)

if __name__ == "__main__":
    main()
このスクリプトではdivide()関数内で例外をキャッチし、エラーメッセージを表示した後、traceback.print_exc()を呼び出してトレースバックを表示しています。
tracebackはPythonのデバッグに欠かせない要素です。エラーに至った経路を確認でき、それを抽出しフォーマットするための関数を提供します。例外をキャッチしてtraceback.print_exc()を使用したように、トレースバックの表示方法を制御する機能はデバッグをより簡単に、より効率的にするための強力なツールになります。

importlibでモジュールインポートを強化する

Pythonのimportlibモジュールは、プログラム内でモジュールをインポートするプロセスを制御するために使用できる、強力柔軟なツールです。Pythonのimport文はその最も特徴的な機能の1つであり、モジュラープログラミングやコードの再利用を可能にします。しかし、より複雑なシナリオで動的にモジュールをインポートしたい場合、importlibはその柔軟なインポート機能で役立ちます。
ここではimportlibを使ってmathモジュールを動的にインポートし、それを使っていくつかの計算をするという簡単な例を考えてみましょう。
import importlib

# mathモジュールの動的インポート
math_module = importlib.import_module('math')

# インポートしたモジュールを使用
print(math_module.sqrt(16))  # 出力: 4.0
この例ではimportlib.import_module('math')import mathと同等です。しかし、importlibを使う利点は標準のimport文では不可能なインポートするモジュールを実行時に決めることができることです。
importlibのもう1つの便利な機能はモジュールを再読み込みする機能です。モジュールがインポートされるとPythonはそのモジュールをキャッシュし、以降のインポート呼び出しには同じコピーを再利用します。つまり、モジュールがインポートされた後に変更されてもプログラムが再起動されるか、モジュールが明示的に再ロードされない限りPythonはその変更を見ることができません。
import importlib
import my_module

# モジュールに変更を加える処理が発生

# モジュールの変更を解釈するように再読み込み
importlib.reload(my_module)
このスクリプトではmy_moduleをインポートした後にいくつかの変更を加えています。更新されたバージョンのモジュールを同じプログラム内で使用するために、importlib.reload(my_module)を呼び出して再読み込みしています。
importlibモジュールは、プログラムをより柔軟でダイナミックなものへとするためにこれらの機能やその他の高度なインポート機能を提供します。