フリーキーズ | 独学プログラミング

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

最終更新日
【画像】Pythonのよく使う標準ライブラリ一覧と使い方の例 その4

前回は下記リンクからご覧ください。

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

mimetypesでMIMEを扱う

Pythonのmimetypesライブラリは、ファイルのMIMEタイプと拡張子を判定するのに便利なツールです。MIMEとは、Multipurpose Internet Mail Extensionsの略で、インターネット上のファイルをその性質や形式に応じて識別するための方法です。例えば、MIMEタイプを使うことでブラウザは適切な拡張子を持つファイルを開くことができます。Pythonのmimetypesモジュールは、URLやファイル名からファイルの種類を判断する関数を提供しています。

import mimetypes

# 指定のファイルのMIMEタイプを取得
print(mimetypes.guess_type('myfile.pdf'))  # returns ('application/pdf', None)

この例では与えられたファイルのMIMEタイプを返すguess_type()関数を使用しています。ここでは、myfile.pdfapplication/pdfとして識別されています。

MIMEデータベースとの対話

mimetypesモジュールはMIMEデータベースと対話する方法を提供します。add_type()メソッドを使って新しい型や拡張子をデータベースに追加したり、types_mapを使ってすべての既知のMIMEタイプのリストを取得したりできます。

import mimetypes

# 新しいタイプを追加
mimetypes.add_type('application/x-python-code', '.pyc')

# 追加したタイプを確認
print(mimetypes.guess_type('test.pyc'))  # returns ('application/x-python-code', None)

# すべてのMIMEタイプを表示
print(mimetypes.types_map)

ここではPythonでコンパイルされたファイル用に新しいタイプを追加し、guess_type()でテストしています。そして、既知のMIMEタイプをすべて表示しています。

mimetypesライブラリの有用性

様々な種類のファイルが頻繁にやり取りされる世界では、MIMEタイプを理解し扱うことは必須のスキルです。Pythonのmimetypesライブラリは、このタスクを簡略化しカスタマイズや拡張を容易にします。

import mimetypes

# MIMEタイプに対して有効な拡張子を表示
print(mimetypes.guess_all_extensions('text/html'))  # returns ['.html', '.htm']

# ファイルのエンコードを取得
print(mimetypes.guess_type('myfile.tar.gz'))  # returns ('application/x-tar', 'gzip')

最初の例ではtext/htmlタイプに対して可能なすべての拡張子を見つけるためにguess_all_extensions()メソッドが使用されます。2番目の例では、guess_type()がファイルのエンコーディングも返しています。これはPythonでファイルタイプやエンコーディングを扱う際のmimetypesの実用的な使い方を示しています。

base64でバイナリデータを処理する

Pythonのbase64モジュールは、バイナリデータをASCII文字にエンコードおよびデコードするための重要なツールです。バイナリデータをエンコードする必要がある場合、特にテキストを扱う目的で設計されたプロトコル上において、データを送信する必要があるケースで使用される技術です。画像や文書など、送信や保存に安全な形式へと変換する必要がある特定の種類のファイルを扱っている場合に便利です。

import base64

# 文字列をエンコード
string = "Hello, Python!"
encoded_string = base64.b64encode(string.encode())
print(encoded_string)  # returns b'SGVsbG8sIFB5dGhvbiE='

ここでは単純な文字列Hello, Python!をエンコードしています。b64encode()関数はbytesライクなオブジェクトを必要とするので、まずencode()を使って文字列をbytesに変換しています。

base64のエンコードとデコードを扱う

base64モジュールはデータをエンコードおよびデコードするための一連の関数を提供します。データをエンコードした後、デコードして元の形式に戻す必要のある場合があります。これはb64decode()関数を使用して行うことができます。

import base64

# エンコードされた文字列をデコードする
decoded_string = base64.b64decode(encoded_string).decode()
print(decoded_string)  # returns 'Hello, Python!'

b64decode()はbytesのようなオブジェクトを返し、decode()で文字列に戻します。

base64の実用性

base64モジュールは多くの実用的なケースで有用であることが証明されています。典型的な使用例としては、複雑さを隠したい場合やデータの保存や転送の際に意図しない改変からデータを保護する必要がある場合です。また、base64でエンコードされたデータを必要とするAPIを使用する場合にも使用されます。

import base64

# 画像ファイルのエンコード
with open("test.png", "rb") as image_file:
    encoded_string = base64.b64encode(image_file.read())
    print(encoded_string)  # prints the encoded image

ここでは画像ファイルをバイナリモードで開き、その内容を読み取りエンコードしています。特殊文字による破損を心配することなく、安全に送信・保存できます。

xmlでXML形式のデータを操作する

Pythonのxmlライブラリは、XMLデータを解析・作成するための堅牢なツールです。XML(Extensible Markup Language)はHTMLによく似たマークアップ言語です。XMLは設定ファイルやWebサービスなどのデータ保存やデータ転送によく使われ、文書ファイル形式としても機能します。Pythonのxmlライブラリには、xml.domxml.saxxml.etree.ElementTreeモジュールなど、XMLをパースするための様々なモジュールが付属しています。

from xml.etree import ElementTree

# シンプルなXMLデータを作成
root = ElementTree.Element("root")
child = ElementTree.SubElement(root, "child")
child.text = "This is a child node"

tree = ElementTree.ElementTree(root)
tree.write("sample.xml")

この例ではElementTreeモジュールを使って、1つのルートノードと1つの子ノードを持つ単純なXMLデータを作成します。

xmlライブラリによるXMLデータのパース

XMLデータの解析はxmlライブラリの真価が問われるところです。XMLドキュメントを読み込んでデータを抽出したり、必要に応じて操作したりできます。

from xml.etree import ElementTree

# XMLファイルのパース
tree = ElementTree.parse('sample.xml')
root = tree.getroot()

# 子ノードを表示
for child in root:
    print(child.tag, child.text)

ここでは先に作成したsample.xmlファイルを読み込んでいます。ファイルを読み込むにはparse()関数を使い、ルート要素を取得するにはgetroot()を使用します。そして、各子ノードのタグとテキストを表示しています。

xmlライブラリの有用性

xmlライブラリは特にデータ交換やWebサービスを扱うPython開発者のツールボックスにおいて重要なツールです。多くのAPIやWebサービスでは、通信にXML形式を使用しており、Pythonのxmlライブラリを使用すればそのようなデータの取り扱いが効率的になります。

from xml.etree import ElementTree as ET

# 文字列からXMLデータを作成
xml_data = '''<root>
                  <child>This is a child node</child>
              </root>'''

root = ET.fromstring(xml_data)
print(root.tag, root[0].text)  # 出力: 'root This is a child node'

この例では、ET.fromstring()を使って文字列からXMLデータをパースする方法を紹介します。これはXMLレスポンスを返すAPIを扱うときに便利です。

urllibでURLやHTTPリクエストを操作する

Pythonのurllibライブラリは、URLを扱うためのPythonの標準ユーティリティモジュールが付属しているパッケージです。HTTPリクエストの送信、リクエストヘッダの変更、URLの解析など、HTTPやURLに関連する多くのタスクのための機能性を提供します。

import urllib.request

response = urllib.request.urlopen('http://example.com')
print(response.status)

ここではurllib.request.urlopenを使用して、Webサイトへの簡単なHTTPリクエストを行っています。レスポンスオブジェクトのstatus属性は、HTTPステータスコードを教えてくれます。

urllibによるURL解析と引用符の処理

urllibにはURLを構成要素に分解し、URLのエンコード/デコードを処理するためのurlparsequoteモジュールも含まれています。

from urllib.parse import urlparse, unquote, quote

parsed_url = urlparse('http://example.com/path?query=python%20urllib')
print('Scheme:', parsed_url.scheme)
print('Netloc:', parsed_url.netloc)
print('Path:', parsed_url.path)
print('Unquoted query:', unquote(parsed_url.query))

url = 'http://example.com/path?query=' + quote('python urllib')
print('Quoted URL:', url)

ここでurlparseはURLを構成要素に分解します。unquoteはURLエンコードされた文字列をデコードし、quoteはその逆を行います。

urllibでHTTPヘッダとPOSTデータを扱う

urllibではリクエストの中でHTTPヘッダを扱ったり、POSTデータを送信したりできます。これはWebスクレイピングやAPI利用のように、ヘッダーやPOSTデータが重要な役割を果たすタスクに不可欠です。

from urllib.request import Request, urlopen
from urllib.parse import urlencode

headers = {'User-Agent': 'Mozilla/5.0'}
data = urlencode({'key1': 'value1', 'key2': 'value2'}).encode()

request = Request('http://httpbin.org/post', data=data, headers=headers)
response = urlopen(request)

print(response.read().decode())

この例ではヘッダーにUser-Agentを設定し、urlencodeを使用してPOSTデータを送信しています。データはシンプルなHTTPリクエスト/レスポンスサービスである http://httpbin.org/post に送信されます。

httpで行われるHTTP操作の基礎を学ぶ

Pythonのhttpモジュールは、HTTP関連のモジュールやクラスを集めたパッケージです。直接使うことはあまりありませんがhttp.serverhttp.clientなど、サーバーやクライアントの機能を提供する他のモジュールの基礎となっています。

ここではHTTPリクエストを送信できるhttp.clientモジュールの簡単な使い方を紹介します。

import http.client

conn = http.client.HTTPSConnection("www.python.org")
conn.request("GET", "/")
res = conn.getresponse()

print(res.status)

このコードでは、www.python.orgへの接続を確立し、GETリクエストを送信し応答ステータスを取得しています。

http.serverによるシンプルなHTTPサーバーの構築

http.serverはシンプルで強力なモジュールで、わずか数行のコードでHTTPサーバーを作成できます。これは迅速なテストサーバーを作成するのに非常に便利です。

from http.server import SimpleHTTPRequestHandler, HTTPServer

handler = SimpleHTTPRequestHandler
server = HTTPServer(('localhost', 8000), handler)

print("Serving at port", 8000)
server.serve_forever()

上記の例ではポート8000localhostのカレントディレクトリからファイルを提供する単純なHTTPサーバーを作成しています。

http.HTTPStatusでHTTPステータスコードに潜入する

http.HTTPStatusはHTTPステータスコードを表します。HTTPレスポンスを扱う際にレスポンスのステータスを確認したい場合に便利です。

from http import HTTPStatus

print(HTTPStatus.OK)
print(HTTPStatus.NOT_FOUND)

これは以下を出力します。

HTTPStatus.OK
HTTPStatus.NOT_FOUND

HTTPStatus.OK200のステータスコード、HTTPStatus.NOT_FOUND404のステータスコードを表していることを表しています。

uuidで一意な識別子を生成する

Pythonのuuidモジュールは、UUID(universally unique identifiers)の生成に使用されます。UUIDは128ビットの値で、グローバルに一意であるため、衝突(同じUUIDを複数回生成すること)の確率が極めて低くなっています。データベースや分散システムなど、一意な識別子が必要な場合によく使われます。

uuidモジュールの基本的な使い方はランダムなUUIDを生成することです。以下はその例です。

import uuid

generated_uuid = uuid.uuid4()
print(generated_uuid)

このスクリプトではuuid4関数がランダムなUUIDを生成します。これを実行すると、123e4567-e89b-12d3-a456-426655440000のようなUUIDを出力します。

その他のUUIDの種類

uuidモジュールはランダムなUUID以外にも、以下のような手法でUUIDを生成できます。

  • ホストID + シーケンス番号 + 現在時刻から生成(uuid1
  • DNS名前空間から生成(uuid3
  • またはSHA-1ハッシュから生成(uuid5
# ホストID + シーケンス番号 + 現在時刻から生成
uuid1 = uuid.uuid1()
print(f"UUID1: {uuid1}")

# DNS名前空間から生成
name = "example.com"
namespace = uuid.NAMESPACE_DNS
uuid3 = uuid.uuid3(namespace, name)
print(f"UUID3: {uuid3}")

# SHA-1ハッシュから生成
uuid5 = uuid.uuid5(namespace, name)
print(f"UUID5: {uuid5}")

UUIDを生成するこれらの他の方法は特定の要件に対して有用です。

UUIDのフィールドと表現

UUIDはUUID標準の一部であるいくつかのフィールドで構成されています。これらのフィールドにはUUIDオブジェクトの属性でアクセスできます。

# UUIDのバージョンを表示
print(f"UUID version: {generated_uuid.version}")

# 48bitノードの値として表示
print(f"UUID node: {generated_uuid.node}")

# 32文字の16進文字列として表示
print(f"UUID as hex: {generated_uuid.hex}")

UUIDのバージョン番号、48ビットのノード値、32文字の16進文字列として表現されたUUIDが出力されます。これらのUUIDフィールドを理解することはより高度なユースケースに役立つことがあります。

xmlrpcでXML-RPCを操作する

Pythonのxmlrpcライブラリは、XML-RPCプロトコルを使用して、異なるマシンで動作し、異なる言語で書かれた可能性のあるソフトウェア間の通信を可能にする強力なツールです。このライブラリにはXML-RPCクライアントとサーバーの両方を作成するためのモジュールが含まれています。

まずPythonによるXML-RPCサーバーの基本的な例から見ていきましょう。

from xmlrpc.server import SimpleXMLRPCServer

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

server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(add_numbers, "add")
server.serve_forever()

この例ではローカルマシンのポート8000でリッスンするXML-RPCサーバを作成します。このサーバーはクライアントからリモートで呼び出すことができる関数add_numbersを提供します。

XML-RPCクライアントの作成

サーバを作成したのでサーバと通信するクライアントを作成します。クライアントはサーバーが提供するadd_numbers関数を呼び出すことができます。

import xmlrpc.client

with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:
    print("3 + 5 = %s" % str(proxy.add(3, 5)))

このスクリプトでは先に起動したサーバーへ接続するXML-RPCクライアントを作成しています。クライアントはadd関数(サーバではadd_numbers関数)を呼び出し、3、5という数字を渡しています。

XML-RPCにおけるエラーの処理

xmlrpcライブラリはリモートプロシージャコール中に発生する可能性のあるエラーを処理する方法も提供しています。FaultクラスはXML-RPCのフォルト(XML-RPCサーバーのエラー)を表します。

from xmlrpc.client import ServerProxy, Fault

try:
    with ServerProxy("http://localhost:8000/") as proxy:
        print(proxy.divide(1, 0))  # This will raise a ZeroDivisionError on the server
except Fault as fault:
    print(f"XML-RPC fault code: {fault.faultCode}")
    print(f"XML-RPC fault string: {fault.faultString}")

このスクリプトではXML-RPCのフォルトが発生したときに発生するFault例外をキャッチしています。サーバーがZeroDivisionErrorに遭遇するとクライアントに失敗したことを送信し、それを処理してプリントアウトできます。

gettextで国際化(i18n)を実現する

Pythonのgettextは、国際化(i18n)を意識したアプリケーションを開発する上で重要なライブラリです。このライブラリはメッセージカタログにアクセスするための柔軟でわかりやすいAPIを提供することで、Pythonのプログラムを多言語にローカライズ(翻訳)する方法を提供しています。

次の例ではgettextを使って簡単な挨拶メッセージをフランス語に翻訳する方法を説明します。

import gettext

# フランス語の'translation'インスタンスの生成
fr = gettext.translation('myapplication', 'locale', languages=['fr'])

# アプリケーション全体にインスタンスをインストール
fr.install()

# _()関数が全体で使えるようになり翻訳できる
print(_("Hello, World"))

この例ではlocale/fr/LC_MESSAGES/ディレクトリにあるmyapplication.moファイルが、メッセージ"Hello, World"のフランス語訳を内包していると仮定しています。

gettextでメッセージカタログを作成する

gettextを使う前に、メッセージカタログ(サポートしたい各言語の翻訳を含むファイル)を作成する必要があります。ソースコードから翻訳可能な文字列を抽出するためにpygettextツールを使用し、バイナリの.moファイルへコンパイルするためにmsgfmtを使用します。

# 翻訳する文字列を抽出
pygettext -d myapplication myapplication.py

# 生成された.potファイル内のメッセージを翻訳し、.poとして保存する
# この手順は通常、手動で行う

# .poファイルをコンパイルし.moファイルにする
msgfmt myapplication.po -o myapplication.mo

複数形のサポート

gettextライブラリは言語によって大きく異なる可能性のある複数形をサポートしています。ngettextメソッドがこれを処理します。

n = 3
print(ngettext("There is %d file", "There are %d files", n) % n)

ここではngettextが数字nに基づいて正しい形を選択しています。これはgettextのパワーのほんの一例で、コンテキストサポートやフォールバック翻訳などもっと多くの機能があります。

localeでシステムの地域設定をする

Pythonのlocaleモジュールは、POSIXロケールデータベースと機能へのゲートウェイとしての役割を担っています。これは言語、通貨フォーマット、日付と時刻の表記などに影響を与え、プログラムが地域設定と相互作用する方法をカスタマイズするための優れたツールです。

ここでは、ロケールを特定の言語環境に設定する方法の例を示します。例えば、UTF-8エンコーディングの米国英語を表すen_US.UTF-8を使ってみましょう。

import locale

locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

ロケールを設定した後はロケールメソッドを使って、地域設定に応じた文字列の書式を設定できます。

Pythonのlocaleを使った数値の書式設定

localeモジュールには現在または指定されたロケールに準拠した方法で数値をフォーマットする機能があります。例えば、千の区切り文字を使った数値の書式設定や、浮動小数点数をロケール固有の小数点で書式設定したい場合があります。

import locale

locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

# ロケールを意識した数値の書式設定
print(locale.format("%d", 1234567, grouping=True))  # 出力: '1,234,567'

# 浮動小数点数のロケールを意識した書式設定
print(locale.format("%.2f", 1234567.89, grouping=True))  # 出力: '1,234,567.89'

上記のコードでは%d%.2fprintfスタイルのような標準的な書式指定ですが、locale.format()と併用するとロケールを意識した書式になります。

localeの他の機能を探る

数値の書式以外にもlocaleはPythonの日付、時刻、通貨の表示方法にも影響します。localeモジュールにはロケールに応じた文字列を比較するlocale.nl_langinfo(), locale.currency()など、これらを扱うための関数があります。

import locale

locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

# 通貨をフォーマット
print(locale.currency(1234567.89))  # 出力: '$1234567.89'

# 現在のロケールに応じた最初の平日を取得
print(locale.nl_langinfo(locale.FIRST_WEEKDAY))  # 出力: '1'

これらの機能によりユーザーの言語や文化的慣習に配慮したプログラムを作成し、ユーザビリティやアクセシビリティを向上させることができます。

tkinterでGUIアプリを作成する

tkinterは、Tk GUIツールキットへの標準的なPythonインターフェースです。PythonでGUIアプリケーションを作成するための最も簡単で迅速な方法の1つです。Pythonがインストールされている場合、tkinterはPythonに標準パッケージとして同梱されているのでほとんどの場合、すぐに使うことができます。

tkinterを使ってウィンドウを作成するのは非常に簡単です。以下は非常に基本的な例です。

from tkinter import Tk

root = Tk()  # トップレベルウィンドウを作成
root.mainloop()  # Tkイベントループを起動

上記のコードを実行すると新しいウィンドウがポップアップ表示されます。このウィンドウはボタン、ラベル、テキストボックスなどを追加するためのキャンバスとなります。

Tkinterでウィジェットを作成する

ウィジェットはGUIを構成する要素です。tkinterには、LabelButtonTextEntryなど、数多くのウィジェットが用意されています。ウィジェットを使用するにはまずクラスのインスタンスを作成し、それをウィンドウに追加する必要があります。

ここではLabelButtonを作成する簡単な例を示します。

from tkinter import Tk, Label, Button

root = Tk()

label = Label(root, text="Hello, Tkinter!")  # ラベルを作成
label.pack()  # ウィンドウに追加

button = Button(root, text="Click me!")  # ボタンを作成
button.pack()  # ウィンドウに追加

root.mainloop()

pack()メソッドはtkinterのジオメトリマネージャの1つです。このメソッドは、親ウィンドウ内でウィジェットに割り当てられたスペースを提供する責任を負います。

tkinterウィジェットとのインタラクション

ButtonEntryのようなウィジェットには、特定のイベントにPythonの関数を関連付けるオプションが用意されています。

ここではボタンをクリックしたときに関数をバインドする基本的な例を示します。

from tkinter import Tk, Button

def say_hello():
    print("Hello, Tkinter!")

root = Tk()

button = Button(root, text="Click me!", command=say_hello)
button.pack()

root.mainloop()

上のコードではボタンをクリックするとsay_hello関数が呼び出され、コンソールにメッセージが出力されます。これは氷山の一角にすぎません。tkinterは様々なユーザーインタラクションを持つ複雑なGUIアプリケーションを作成できます。

typingでタイプヒンティングを導入する

Pythonのtypingモジュールは、Pythonがタイプヒントをサポートするための基本的な部分です。Python 3.5でPython言語をより堅牢にする手段として導入されました。型付けモジュールを使用することで入力と出力の期待される型を指定でき、コードのデバッグやコードの理解を深め、IDEをより便利なものにできます。

以下はタイプヒントを使った関数の例です。

from typing import List

def greet_all(names: List[str]) -> None:
    for name in names:
        print(f"Hello, {name}!")

greet_all(["Taro", "Hanako"", "Bob"])

この例ではnamesは文字列のリストであることが期待されます。この関数は何も返さないのでNoneと表記されます。

より複雑な型の使用

typingモジュールには、Optional、TupleDictなど、さまざまな複雑な型を表すクラスが用意されています。例えば、文字列やNoneを返す関数がある場合、Optional[str]を戻り値型として使用できます。

以下はその例です。

from typing import Optional

def find_first(names: List[str], target: str) -> Optional[int]:
    try:
        return names.index(target)
    except ValueError:
        return None

print(find_first(["Alice", "Bob", "Charlie"], "Bob"))
print(find_first(["Alice", "Bob", "Charlie"], "David"))

上記の例では関数find_firstnamesの中からtargetのインデックスを探そうとします。見つかった場合はそのインデックス(整数)を返し、そうでない場合はNoneを返します。

mypyによる型チェック

Pythonのインタプリタは型ヒントを強制しませんが、mypyという別のツールがあり、それを使ってコードの型の整合性をチェックできます。これは「静的型チェック」と呼ばれています。

ここではPythonスクリプトに対してmypyを実行する方法を説明します。

$ mypy my_script.py

先ほどの例ではmypyは何もエラーを報告しませんでした。しかし、greet_all(123)を呼び出そうとすると、文字列のリストを渡していないためmypyがエラーを報告します。

Pythonの型付けモジュールとmypyツールは、あなたのコードをより堅牢で理解しやすくするためにあることを忘れないでください。これらは完全にオプションであり、あなたのコードを改善するためのツールとして使用されるべきであり、要件として使用するものではありません。

pydocでドキュメントを作成する

Pythonプログラミングの領域では、特に複雑なプログラムを扱う場合、コードの一部が何をするのかを理解するためにドキュメントが重要な役割を果たします。Pythonに内蔵されているpydocモジュールは、Pythonモジュールに関するドキュメントを作成したり、有用な情報を入手したりするための素晴らしいツールです。

ここではPythonスクリプトの中からpydocを使用する方法を説明します。

import pydoc

# モジュールに関するヘルプの取得
print(pydoc.getdoc(pydoc))

# モジュールの場所を表示する
print(pydoc.locate('os'))

上記の例ではgetdocを使ってpydocモジュール自体の簡単なドキュメントを取得しています。また、ファイルシステム上のosモジュールの場所を見つけるためにlocateを使用しています。

pydoc CLIの使用法を理解する

pydocモジュールにはターミナルから直接使用できるコマンドラインインターフェイス (CLI) も付属しています。これはターミナルを離れることなくモジュールや関数のヘルプを得るのに特に便利です。pydoc CLIにアクセスするにはpydocと入力し、その後にヘルプを得たいモジュールまたは関数の名前を入力します。

以下はその例です。

$ pydoc os

上の例ではPythonのosモジュールの説明、クラス、関数などに関するヘルプページが端末に表示されます。

pydocでHTMLドキュメントを生成する

pydocの強力な機能の1つに、ドキュメントを含むHTMLページを生成する機能があります。これはCLIで-wフラグを使用することで実現できます。これは指定されたモジュールのHTMLページを作成しカレントディレクトリに保存します。

ここではosモジュールのHTMLページを生成する方法を説明します。

$ pydoc -w os

doctestで関数やクラスのドキュメントにテストを仕込む

doctestモジュールは、Pythonのプログラム、特に関数、メソッド、およびクラスのドキュメントにテストを埋め込むための独創的な方法です。この機能はコードの文書化とテストのベストプラクティスを同時に促進します。

def add(a, b):
    """
    This function adds two numbers.

    >>> add(2, 2)
    4
    >>> add(8, 2)
    10
    """
    return a + b

import doctest
doctest.testmod(verbose=True)

上の例では2つの数値を合計する関数addを定義しています。docstringにはこの関数の呼び出し例と、予想される結果を>>>プロンプトに従って記述しています。そして、doctest.testmod()関数は実際の結果が期待される結果と一致するかどうかをチェックします。

ドキュメンテーションとテストにおけるdoctestの威力

doctestモジュールは関数と期待される出力の説明を書くことを促し、コードをより読みやすく貴重なツールです。doctestは関数が期待通りに動作することを検証するための軽量な方法であり、簡単なテストやシンプルで説明的な例を文書化するために優れています。

def factorial(n):
    """
    Return the factorial of n, an exact integer >= 0.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000
    """
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)

import doctest
doctest.testmod()

この例では関数factorialを定義し、docstring内でいくつかの使用例を提供しています。doctest.testmod()関数はfactorial関数が期待される出力を生成するかどうかをチェックする。

スクリプトの外でテストを実行する

doctestはモジュール、関数、クラス、メソッドなど、あらゆるオブジェクトのdocstringに含めることができます。また、doctestモジュールはファイル内のすべてのdoctestをチェックできるコマンドラインインターフェイスを提供します。これを使うにはPythonに-m doctestオプションを付けてファイル名を指定します。

$ python -m doctest -v example.py

上のコマンドでは-vフラグで詳細な出力を表示するverboseモードが有効になっています。

続きは下記リンクからご覧ください。

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

関連するコンテンツ