前回は下記リンクからご覧ください。
Pythonのよく使う標準ライブラリ一覧と使い方の例 その2
argparse
はコマンドラインインタフェースを作成するためのPython標準ライブラリモジュールです。プログラムが必要とする引数を定義し、sys.argv
からそれらの引数を解析する方法を見つけ出すプロセスを簡略化できます。
argparse
でパーサーを作成することはコマンドライン引数を管理するための最初のステップです。パーサーを初期化し、必要な引数を追加します。引数には、オプションと位置指定(必須)があります。以下はパーサーを作成し、オプションの引数を追加する例です。
この例ではオプションの引数--name
を用意しています。ユーザーがこの引数を指定しない場合、そのデフォルト値名無し
が使用されます。
オプションの引数とは別に、argparse
では位置指定(必須)の引数を指定できます。オプションの引数とは異なり、位置指定引数は--name
のような名前を前に付ける必要がありません。先ほどのスクリプトを修正して、必須の位置引数を入れてみましょう。
ここで、location
は必須引数です。ユーザがこの引数を与えなかった場合、argparse
はエラーメッセージを表示しスクリプトはそれ以上進みません。
Pythonのgetopt
モジュールは、コマンドラインのオプションと引数を解析するもう1つの方法です。argparse
と同様にユーザーフレンドリーなコマンドラインインターフェイスを作成するのにも役立ちます。getopt
モジュールはsys.argv[1:]
を処理し、オプション、引数などのペアのリストとオプション以外の引数のリストを返します。
getopt
を使うには期待するオプションを定義する必要があります。getopt.getopt
関数は、解析するコマンドライン引数(通常はsys.argv[1:]
)、ショートオプション、ロングオプションの3つの引数を取ります。ショートオプションにはダッシュが1つ付き、グループ化できます。ロングオプションは先頭にダッシュが2つ付いています。以下は簡単な例です。
上のコードでは、h
、o:
、v
が短いオプション(o
の後のコロンは引数が必要という意味)、help
、output=
、verbose
が長いオプションとなります。
特定のオプションに引数を要求するように指定できます。getopt
に渡すオプション文字列では上のo
オプションに見られるように、引数を必要とするオプションはコロンを付ける必要があります。以下に、この使い方の例を示します。
このコードではo
オプションは引数を必要とし、出力ファイルの名前を示しています。このスクリプトをコマンドラインから実行し、-o output.txt
または--output output.txt
を含めると出力されます。出力ファイルはoutput.txt
と表示されます。
logging
モジュールは、ソフトウェアの実行時に発生するイベントを追跡するための強力な組み込みPythonライブラリです。Pythonプログラムからログメッセージを出力するための柔軟なフレームワークを提供します。print
文を使うよりも堅牢で柔軟性があり、ログを分類したり、ログメッセージのレベルに基づいて何をすべきかを決定したり、といったいくつかの利点があります。ここではlogging
モジュールを使用する簡単な例を示します。
上記の例ではlogging
モジュールをインポートし、logging.warning()
を呼び出して警告メッセージを表示させています。logging
モジュールはイベントの重大性を示す5つの標準レベルを定義しています。DEBUG、INFO、WARNING、ERROR、CRITICALです。
logging
モジュールを効果的に使用するためにログメッセージのレベルやフォーマットを指定する設定が可能です。basicConfig(**kwargs)
メソッドを使ってlogging
の設定できます。
上のコードでは、レベルをDEBUGに設定していますが、これはこのレベル以上のものをキャプチャすることを意味します。また、ロギング時刻、ロガー名、重大度レベル、メッセージを含むように形式を設定しています。
コンソールにメッセージを表示するだけでなくログ出力をファイルに出力可能です。これは長時間プログラムを実行し、後でログを分析したい場合に便利です。ここではメッセージをファイルに記録する方法を説明します。
上記のコードでは、basicConfig
メソッドのfilename
パラメータを使ってログファイルの名前を指定しています。ログメッセージはapp.log
に書き込まれます。レベルをWARNINGにすることで、WARNING以上のイベントのみをログへ記録するようにしています。
Pythonのgetpass
モジュールは、ユーザーのパスワードやその他の機密情報を管理する際に便利なツールです。主に、パスワードのような機密性が要求されるユーザー入力を扱うために、ユーザーが入力した内容をコンソール上でエコーしないよう使用します。ここでは、getpass
の使い方を説明します。
この例ではgetpass
モジュールをインポートし、getuser()
でユーザーのログイン名を取得し、getpass()
でユーザーにパスワードを表示させずに尋ねています。
getpass
モジュールの主な使用例はPythonプログラムでのパスワード処理です。これにより、ユーザは他人に見られる心配をすることなく、機密情報を入力できます。これは入力された各文字をアスタリスク(*
)に置き換えたり、単に何も表示しないことで実現されます。
上記のコードスニペットでは、getpass.getpass()
を使用してユーザーのパスワードを尋ねています。ユーザーが入力しても表示されません。
getpass
モジュールについて注意すべき点はその動作がプラットフォームによって異なる場合があることです。Unixではechoをオフにし、Windowsではパスワードダイアログを使用します。安全な入力ができない状況ではgetpass
は警告を出す可能性があります。
この例ではgetpass
の使用で発生する可能性のある例外を安全な方法で処理します。
Pythonのplatform
モジュールは、ハードウェア、オペレーティングシステム、インタプリタのバージョン情報など、基盤となるプラットフォームのデータへアクセスするために使用します。これはコードの中でプラットフォームに依存した判断をする必要がある場合や、異なるプラットフォーム間でデバッグを行う場合に役立つことがあります。
このコードでは、platform.system()
は、Linux
、Windows
、Darwin
のようにオペレーティングシステムの名前を返します。platform.release()
関数はシステムのリリースバージョンを返します。
platform
モジュールは実行中のPythonのバージョンやビルド番号など、Pythonインタプリタ自体の詳細も知ることができます。
このスニペットでは、python_version()
はPythonのバージョンを文字列として提供し、python_build()
はビルド番号と日付を文字列として含むタプルを返しています。
さらにplatform
モジュールはハードウェア情報にアクセスできます。これにはマシンタイプやプロセッサ情報などのデータが含まれ、ハードウェアによって実行経路が異なるスクリプトには非常に便利です。
この例ではplatform.machine()
は、i386
のようなマシンタイプを返します。platform.processor()
関数はシステムのプロセッサについてのより具体的な情報を提供します。
Pythonのthreading
モジュールはマルチスレッドプログラミングのために使用されます。スレッドとは、オペレーティングシステムで同時に実行できる最小の実行単位です。マルチスレッドの主な利点は、複数のタスクが互いに干渉することなく同時に実行できるようになることです。
上記のコードでは、threading.Thread()
を使って2つのスレッドを作成し、それぞれ関数print_numbers()
とprint_letters()
に関連付けしています。スレッドはstart()
メソッドで開始されます。
スレッドは独立して実行できますが、時には実行を同期させる必要があります。そのための1つの方法として、スレッドモジュールのLock
オブジェクトを使用します。
この例ではacquire()
メソッドがLock
オブジェクトをロックし、1つのスレッドだけが一度にコードブロックを実行できるようにします。実行が完了したら、release()
メソッドを呼び出してLock
オブジェクトのロックを解除し、他のスレッドが処理を進められるようにします。
Pythonのスレッド化によって特定の種類のプログラムを高速化できますが、GILがあるため、すべてのPythonコードをスレッド化によって高速に動作するわけではないことを知っておくことが重要です。GILは1つのプロセスで同時に1つのスレッドしかPythonバイトコードを実行できない仕組みで、CPUバウンドプログラムではスレッド化による性能が制限されることもあります。
このコードではslow_operation()
はIOバウンド操作(入出力を待つ操作、この場合はsleep
)です。待機中はGILが解放されるため、この間に他のスレッドが実行できるようになります。つまり、PythonにGILがあってもIOバウンドのタスクではスレッド化によって大幅な高速化が可能なのです。
Pythonのmultiprocessing
モジュールは、プロセスを作成でき、ローカルおよびリモートの同時実行を提供します。プロセスとはプログラム(Pythonインタプリタなど)のインスタンスであり、システム内でタスクを実行するものです。multiprocessing
モジュールはPythonの複数スレッドの実行を制限するGIL (Global Interpreter Lock)を克服するのに有効です。
上記のコードでは別々のプロセスで実行される2つの関数print_numbers
とprint_hello
を定義しています。
プロセス間のデータ共有はスレッディングとは異なる方法で行われます。multiprocessing
モジュールでは、プロセス間でデータを共有するためにValue
やArray
を用意しています。以下は簡単な例です。
両方のプロセスがアクセスし変更できる整数を保存するために共有されたValue
を使用しています。
multiprocessing
では、プロセス間の通信経路としてQueue
とPipe
の2種類、プロセス作成APIとしてProcess
とPool
の2種類をサポートしています。Pool
はワーカーのプールで使用するプロセスを一定数作成したい場合に使用します。以下は簡単な例です。
このコードでは、ワーカープロセスのプールを作成し、map
関数を使って関数とイテラブルを各プロセスにマッピングしています。
Pythonのconcurrent.futures
モジュールは、非同期で実行される関数のための高レベルのインターフェイスを提供します。このモジュールは、非同期I/O、タスクスケジューリング、プロセスプール、スレッドプールを実装しています。シンプルかつ使いやすいAPIでスレッドやプロセスを使ってタスクを同時実行できます。
以下に、簡単な使用例を示します。
このコードでは、ThreadPoolExecutor
を使ってワーカーのプールを作成し、このプールにタスクを投入してFuture
インスタンスを返します。future.result()
は、タスクが完了するまでブロックしてから結果を返します。
map
関数はリストなどの反復可能な項目のすべてに関数を適用して、その結果のリストを返す組み込み関数です。concurrent.futures
でも利用可能で、同じ概念を適用しますが同時並行的に実行されます。
このコードでは、map
関数がリストの各項目にタスク関数を同時に適用しています。
CPUに負荷のかかるタスクを実行する必要がある場合、PythonのスレッドはGILの影響を受けるため、マルチスレッドではなくマルチプロセシングを使用する方がよいです。concurrent.futures
モジュールはこのためにProcessPoolExecutor
クラスを提供します。
このコードは、ThreadPoolExecutor
を使った前の例と同様に動作しますが、スレッドの代わりにプロセスを使用し、複数のCPUやコアを利用してGILによる制限を回避できます。
Pythonのsubprocess
モジュールは、新しいプロセスを生成し、その入力/出力/エラーパイプに接続し、その結果をコードを取得できる強力なツールです。os.system
, os.spawn
, os.popen
など、いくつかの古いモジュールや関数を置き換えることを意図しています。
以下に基本的な使い方の例を示します。
subprocess.run()
関数は引数のリストを受け取ります。リストの最初の項目はコマンドで、残りの項目はコマンドのパラメータです。この場合、コマンドls
はパラメータを持ちません。
subprocess
は失敗することがあります。エラーをコードで正しく処理することが重要です。subprocess
が失敗すると0
以外の完了ステータスが返されます。check=True
引数をsubprocess.run()
関数に渡すと、subprocess
で失敗したときに例外を発生させることができます。
このスクリプトは存在しないファイルのリストを作成しようとします。ls
コマンドは失敗し、0
以外の完了ステータスを返すため、subprocess.run()
はCalledProcessError
例外を発生させています。
より複雑なユースケースにはPopen
クラスを使用できます。このクラスはより柔軟で、新しいプロセスを起動し、その入力/出力/エラーパイプへ接続するために使用できます。これは入出力データが大きすぎてメモリに収まらない場合や、プロセスの実行中に対話する必要がある状況で有用です。
このスクリプトは、grep
プロセスを生成し入力値を送っています。grep
コマンドはpython
という単語を含んでいない行をフィルタリングします。
queue
は複数のスレッド間で安全に情報をやり取りする必要があるスレッドプログラミングにおいて、特に有用なマルチプロデューサー/マルチコンシューマーキューを実装しています。基本的なqueue
はFIFO(First In, First Out)動作を提供します。
以下は、キューを使用する簡単な例です。
このコードでは、まずqueue.Queue()
を使って新しいキューを作成します。次にput()
メソッドでキューに要素を追加します。最後にget()
メソッドで要素を削除して出力します。
queue
モジュールのQueue
クラスにはいくつかの便利なメソッドとプロパティがあります。put()
とget()
の他に、empty()
、full()
、qsize()
メソッドを提供しています。
上のコードではQueue()
コンストラクタに最大サイズが与えられています。empty()
はキューが空かどうか、full()
はキューがいっぱいかどうかをチェックし、qsize()
はキューの現在の大きさを返します。
queue
はスレッドと同時に実装することが多いです。以下の例では、アイテムをキューに入れるプロデューサースレッドと、キューからアイテムを取得するコンシューマースレッドを生成しています。
このコードではproducer()
関数がアイテムをキューに入れ、consumer()
関数がキューからアイテムを取得します。q.join()
メソッドはキュー内のすべてのアイテムが取得され処理されるまでブロックされます。
Pythonのasyncio
ライブラリは標準ライブラリの一部です。コルーチンを使ってシングルスレッドの並行コードを書いたり、ソケットや他のリソースでのI/Oアクセスを多重化したり、サブプロセスのネットワークを管理するインフラを提供します。スレッドやプロセスを使うよりも読みやすく、理解しやすい非同期コードを書くことができるようになります。
ここではasyncio
を使ってタスクを並行して実行する簡単な例を紹介します。
このコードでは両方のタスクからHello,
と表示され、1秒待って両方のタスクからWorld!
と表示されます。
asyncio
の核となるのはコルーチンです。コルーチンはPythonのジェネレータ関数に特化したもので、returnへ達する前に実行を中断し、間接的に別のコルーチンへしばらく制御を渡すことができます。
タスクはコルーチンを同時にスケジュールする状況で使用されます。タスクが作成されるとすぐ実行されるようにスケジュールされます。
以下はその例です。
この例では非同期関数count()
を定義し、asyncio.gather()
を使ってmain()
関数内で3回同時実行しています。
asyncio
では、サーバーやクライアントの作成、ロックやセマフォの管理など、高度な機能もサポートされています。たとえば、次のような簡単なエコーサーバーを作成できます。
このコードではポート8888
でlocalhostサーバを起動し、受信したデータをすべてエコーバック(ユーザーに対し状態を表示すること)するサーバーを定義しています。サーバーはasyncio.start_server()
で起動し、例えばKeyboardInterrupt
などで停止するまで動作します。
デジタル時代の今日、データや通信の安全性を確保することは最も重要なことです。そこで登場するのがSSL(Secure Sockets Layer)です。SSLはネットワークに接続されたコンピュータ間で認証され、暗号化されたリンクを確立するためのプロトコルです。Pythonは標準ライブラリにssl
モジュールを提供しており、これは安全なソケット通信するためのソケットオブジェクトのTLS/SSLラッパーです。
上記のコードではssl.create_default_context()
関数を使用して、プロトコル、証明書など、SSLのデフォルト設定をしています。次にsocket.create_connection()
を使用して、ポート443
のホストwww.python.org
への接続を作成します。context.wrap_socket()
は通常のソケットをSSLでラップするために使用されます。
基本的な接続を設定するだけでなく、ssl
モジュールはSSL関連のタスクを処理するための多くの機能性を提供してくれます。例えば、このモジュールを使ってSSLクライアントとサーバーの両方を作成できます。プロトコルや暗号など、様々なパラメータを要件に応じて指定できます。
上記のコードではssl.SSLContext()
を使用して、特定の設定を持つSSLコンテキストを作成しています。新しいコンテキストで使用するSSLバージョンとして、ssl.PROTOCOL_TLSv1_2
を設定しています。また、証明書を要求する検証モードにはssl.CERT_REQUIRED
をセットしています。他のピアの証明書を検証するために使用するCA(認証局)証明書のセットを読み込むにはcontext.load_verify_locations('ca_certs')
をセットします。
ssl
モジュールの使い方を学ぶことでアプリケーションの安全性を確保できるため大きなメリットがあります。PythonでSSLを理解し管理することは、上記で示したように比較的簡単です。
この例ではssl
モジュールを使ってコンテキストを作成し、それをPythonのurllib.request
で使って安全なHTTPSリクエストを作成しています。この例ではssl
を他のPythonモジュールと組み合わせて使用することで、安全な接続できることを示しています。
信号処理は信号の操作と分析を含む広大で魅力的なテーマです。コンピュータの文脈では、シグナルとはあるイベントが発生したことをプロセスに通知するものです。Pythonのsignal
モジュールを使うとプログラムでシグナルを使ったり扱ったりできます。シグナルハンドラを設定したり、シグナルを無視したりするために使用されるPythonのライブラリの不可欠な部分です。
上記のコードでは、シグナルを処理するための関数signal_handler
を定義しています。そしてこの関数をSIGINT
(通常はControl+Cで発生する)のハンドラとしてsignal.signal()
を使って登録しています。このプログラムを実行し、Control+C
を押すと、プログラムが終了するのではなくシグナルハンドラが呼び出されます。
signal
モジュールは単にハンドラを設定するだけではありません。シグナルを送信したり、シグナルを受信するまでプログラムの実行を一時停止したり、アラームシグナルを管理したりとさまざまな用途に使用できます。
この例ではSIGALRM
を処理するシグナルハンドラを登録しています。次にsignal.alarm(5)
を使用して、5秒後にプロセスへ送信されるアラームシグナルをスケジュールしています。シグナルを受信するとハンドラが起動されます。
signal
モジュールはプログラムの流れを制御し、システムイベントに反応する新しい方法を開きます。これは、非同期タスク、タイムアウト、特定の条件下でのプログラムの実行の中断を扱うときに重要です。Pythonプログラマーなら誰でも知っておくべき強力なツールです。
この最後の例ではSIGINT
を受信したときにプログラムを優雅に終了させるハンドラーを登録します。突然プログラムを終了させるのではなく、プログラムが終了する前にクリーンアップする方法を提供しています。これはsignal
モジュールを使用して、予期せぬイベントをエレガントに処理する堅牢なアプリケーションを構築する方法の基本例です。
JSON(JavaScript Object Notation)形式は、そのコンパクトさと読みやすさからデータ交換のためにWeb上で広く使用されています。Pythonはjson
モジュールを使うことでJSONデータを扱うことができるようになります。json.dumps()
メソッドでPythonオブジェクトをJSON文字列に変換(シリアライズ)し、json.loads()
でJSONデータをオブジェクトにデコード(デシリアライズ)できます。
上記の例ではPython辞書をjson.dumps()
メソッドでJSON文字列に変換しています。出力はJSON形式の文字列となります。
json
モジュールにはJSONデータをファイルへ読み書きするためのメソッドも用意されています。json.dump()
関数はPythonオブジェクトをJSONとしてファイルに書き込み、json.load()
はJSONファイルをPythonオブジェクトに読み返します。
ここではまずjson.dump()
を使ってPython辞書をファイルdata.json
に書き込みます。次に同じファイルを開き、json.load()
を使ってデータをPythonオブジェクトに読み返します。
JSONデータを扱えることは特にAPIやWebアプリケーションを扱うプログラマーにとって重要なスキルです。Pythonのjson
モジュールを使えば、JSONデータの解析やPythonのデータ構造のJSONへの変換が簡単にできます。辞書やリストだけでなく、文字列、数値、ブーリアン値、None、さらに複雑な型もサポートしており、Pythonの武器として汎用性の高いツールを提供します。
最後の例ではより複雑なPythonオブジェクトがJSON文字列に変換されています。このようにPythonのjson
モジュールは強力で直感的に使うことができます。
続きは下記リンクからご覧ください。
Pythonのよく使う標準ライブラリ一覧と使い方の例 その4