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

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

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

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

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

argparseでCLIの引数を管理する

argparseはコマンドラインインタフェースを作成するためのPython標準ライブラリモジュールです。プログラムが必要とする引数を定義し、sys.argvからそれらの引数を解析する方法を見つけ出すプロセスを簡略化できます。

import argparse

パーサを作成する

argparseでパーサーを作成することはコマンドライン引数を管理するための最初のステップです。パーサーを初期化し、必要な引数を追加します。引数には、オプションと位置指定(必須)があります。以下はパーサーを作成し、オプションの引数を追加する例です。

import argparse

# パーサーを作成
parser = argparse.ArgumentParser()

# 引数を追加
parser.add_argument('--name', default='名無し', help='名前を入力してください。')

# 引数をパース
args = parser.parse_args()

print(f"こんにちは、{args.name}!")

この例ではオプションの引数--nameを用意しています。ユーザーがこの引数を指定しない場合、そのデフォルト値名無しが使用されます。

位置決め引数

オプションの引数とは別に、argparseでは位置指定(必須)の引数を指定できます。オプションの引数とは異なり、位置指定引数は--nameのような名前を前に付ける必要がありません。先ほどのスクリプトを修正して、必須の位置引数を入れてみましょう。

import argparse

# パーサーを作成
parser = argparse.ArgumentParser()

# 引数を追加
parser.add_argument('location', help='お住まいの地域を入力してください。')

# 引数をパース
args = parser.parse_args()

print(f"あなたは{args.location}に住んでいます。")

ここで、locationは必須引数です。ユーザがこの引数を与えなかった場合、argparseはエラーメッセージを表示しスクリプトはそれ以上進みません。

getoptで引数取得を便利にする

Pythonのgetoptモジュールは、コマンドラインのオプションと引数を解析するもう1つの方法です。argparseと同様にユーザーフレンドリーなコマンドラインインターフェイスを作成するのにも役立ちます。getoptモジュールはsys.argv[1:]を処理し、オプション、引数などのペアのリストとオプション以外の引数のリストを返します。

import getopt

getoptの基本的な使い方

getoptを使うには期待するオプションを定義する必要があります。getopt.getopt関数は、解析するコマンドライン引数(通常はsys.argv[1:])、ショートオプション、ロングオプションの3つの引数を取ります。ショートオプションにはダッシュが1つ付き、グループ化できます。ロングオプションは先頭にダッシュが2つ付いています。以下は簡単な例です。

import getopt
import sys

short_options = "ho:v"
long_options = ["help", "output=", "verbose"]

try:
    arguments, values = getopt.getopt(sys.argv[1:], short_options, long_options)
except getopt.error as err:
    print (str(err))
    sys.exit(2)

for current_argument, current_value in arguments:
    if current_argument in ("-v", "--verbose"):
        print ("enabling verbose mode")
    elif current_argument in ("-h", "--help"):
        print ("displaying help")
    elif current_argument in ("-o", "--output"):
        print (("enabling output mode (%s)") % (current_value))

上のコードでは、ho:vが短いオプション(oの後のコロンは引数が必要という意味)、helpoutput=verboseが長いオプションとなります。

高度なgetoptの使い方

特定のオプションに引数を要求するように指定できます。getoptに渡すオプション文字列では上のoオプションに見られるように、引数を必要とするオプションはコロンを付ける必要があります。以下に、この使い方の例を示します。

import getopt
import sys

short_options = "o:"
long_options = ["output="]

try:
    arguments, values = getopt.getopt(sys.argv[1:], short_options, long_options)
except getopt.error as err:
    print (str(err))
    sys.exit(2)

for current_argument, current_value in arguments:
    if current_argument in ("-o", "--output"):
        print (("output file is (%s)") % (current_value))

このコードではoオプションは引数を必要とし、出力ファイルの名前を示しています。このスクリプトをコマンドラインから実行し、-o output.txtまたは--output output.txtを含めると出力されます。出力ファイルはoutput.txtと表示されます。

loggingでログメッセージを操作する

loggingモジュールは、ソフトウェアの実行時に発生するイベントを追跡するための強力な組み込みPythonライブラリです。Pythonプログラムからログメッセージを出力するための柔軟なフレームワークを提供します。print文を使うよりも堅牢で柔軟性があり、ログを分類したり、ログメッセージのレベルに基づいて何をすべきかを決定したり、といったいくつかの利点があります。ここではloggingモジュールを使用する簡単な例を示します。

import logging

# コンソールに表示されます
logging.warning('This is a warning message')

上記の例ではloggingモジュールをインポートし、logging.warning()を呼び出して警告メッセージを表示させています。loggingモジュールはイベントの重大性を示す5つの標準レベルを定義しています。DEBUG、INFO、WARNING、ERROR、CRITICALです。

loggingの基本設定

loggingモジュールを効果的に使用するためにログメッセージのレベルやフォーマットを指定する設定が可能です。basicConfig(**kwargs)メソッドを使ってloggingの設定できます。

import logging

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logging.warning('これは警告文です')

上のコードでは、レベルをDEBUGに設定していますが、これはこのレベル以上のものをキャプチャすることを意味します。また、ロギング時刻、ロガー名、重大度レベル、メッセージを含むように形式を設定しています。

ファイルへのログ

コンソールにメッセージを表示するだけでなくログ出力をファイルに出力可能です。これは長時間プログラムを実行し、後でログを分析したい場合に便利です。ここではメッセージをファイルに記録する方法を説明します。

import logging

logging.basicConfig(filename='app.log',
                    level=logging.WARNING,
                    format='%(name)s - %(levelname)s - %(message)s')

logging.warning('これは警告文です')

上記のコードでは、basicConfigメソッドのfilenameパラメータを使ってログファイルの名前を指定しています。ログメッセージはapp.logに書き込まれます。レベルをWARNINGにすることで、WARNING以上のイベントのみをログへ記録するようにしています。

getpassでパスワード入力を取り入れる

Pythonのgetpassモジュールは、ユーザーのパスワードやその他の機密情報を管理する際に便利なツールです。主に、パスワードのような機密性が要求されるユーザー入力を扱うために、ユーザーが入力した内容をコンソール上でエコーしないよう使用します。ここでは、getpassの使い方を説明します。

import getpass

user = getpass.getuser()
password = getpass.getpass('Please enter your password: ')

print(f'User: {user}, Password: {"*" * len(password)}')

この例ではgetpassモジュールをインポートし、getuser()でユーザーのログイン名を取得し、getpass()でユーザーにパスワードを表示させずに尋ねています。

getpassによるパスワード処理

getpassモジュールの主な使用例はPythonプログラムでのパスワード処理です。これにより、ユーザは他人に見られる心配をすることなく、機密情報を入力できます。これは入力された各文字をアスタリスク(*)に置き換えたり、単に何も表示しないことで実現されます。

import getpass

password = getpass.getpass("パスワードを入力してください: ")
print("あなたのパスワードは", '*' * len(password))

上記のコードスニペットでは、getpass.getpass()を使用してユーザーのパスワードを尋ねています。ユーザーが入力しても表示されません。

プラットフォーム固有の動作

getpassモジュールについて注意すべき点はその動作がプラットフォームによって異なる場合があることです。Unixではechoをオフにし、Windowsではパスワードダイアログを使用します。安全な入力ができない状況ではgetpassは警告を出す可能性があります。

import getpass

try:
    password = getpass.getpass()
except Exception as error:
    print('ERROR:', error)
else:
    print('Password entered:', password)

この例ではgetpassの使用で発生する可能性のある例外を安全な方法で処理します。

platformでOSやハードウェアを特定する

Pythonのplatformモジュールは、ハードウェア、オペレーティングシステム、インタプリタのバージョン情報など、基盤となるプラットフォームのデータへアクセスするために使用します。これはコードの中でプラットフォームに依存した判断をする必要がある場合や、異なるプラットフォーム間でデバッグを行う場合に役立つことがあります。

import platform

print(platform.system())
print(platform.release())

このコードでは、platform.system()は、LinuxWindowsDarwinのようにオペレーティングシステムの名前を返します。platform.release()関数はシステムのリリースバージョンを返します。

PlatformでPythonのバージョンを取得する

platformモジュールは実行中のPythonのバージョンやビルド番号など、Pythonインタプリタ自体の詳細も知ることができます。

import platform

print(platform.python_version())
print(platform.python_build())

このスニペットでは、python_version()はPythonのバージョンを文字列として提供し、python_build()はビルド番号と日付を文字列として含むタプルを返しています。

ハードウェア情報へのアクセス

さらにplatformモジュールはハードウェア情報にアクセスできます。これにはマシンタイプやプロセッサ情報などのデータが含まれ、ハードウェアによって実行経路が異なるスクリプトには非常に便利です。

import platform

print(platform.machine())
print(platform.processor())

この例ではplatform.machine()は、i386のようなマシンタイプを返します。platform.processor()関数はシステムのプロセッサについてのより具体的な情報を提供します。

threadingでマルチスレッドを操作する

Pythonのthreadingモジュールはマルチスレッドプログラミングのために使用されます。スレッドとは、オペレーティングシステムで同時に実行できる最小の実行単位です。マルチスレッドの主な利点は、複数のタスクが互いに干渉することなく同時に実行できるようになることです。

import threading

def print_numbers():
    for i in range(10):
        print(i)

def print_letters():
    for letter in 'abcdefghij':
        print(letter)

thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)

thread1.start()
thread2.start()

上記のコードでは、threading.Thread()を使って2つのスレッドを作成し、それぞれ関数print_numbers()print_letters()に関連付けしています。スレッドはstart()メソッドで開始されます。

スレッドを同期させる

スレッドは独立して実行できますが、時には実行を同期させる必要があります。そのための1つの方法として、スレッドモジュールのLockオブジェクトを使用します。

import threading

lock = threading.Lock()

def print_numbers():
    lock.acquire()
    for i in range(10):
        print(i)
    lock.release()

def print_letters():
    lock.acquire()
    for letter in 'abcdefghij':
        print(letter)
    lock.release()

thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)

thread1.start()
thread2.start()

この例ではacquire()メソッドがLockオブジェクトをロックし、1つのスレッドだけが一度にコードブロックを実行できるようにします。実行が完了したら、release()メソッドを呼び出してLockオブジェクトのロックを解除し、他のスレッドが処理を進められるようにします。

スレッドセーフとグローバルインタープリタロック

Pythonのスレッド化によって特定の種類のプログラムを高速化できますが、GILがあるため、すべてのPythonコードをスレッド化によって高速に動作するわけではないことを知っておくことが重要です。GILは1つのプロセスで同時に1つのスレッドしかPythonバイトコードを実行できない仕組みで、CPUバウンドプログラムではスレッド化による性能が制限されることもあります。

import threading
import time

def slow_operation():
    time.sleep(5)  # これはIOバウンド操作です

thread1 = threading.Thread(target=slow_operation)
thread2 = threading.Thread(target=slow_operation)

thread1.start()
thread2.start()

このコードではslow_operation()はIOバウンド操作(入出力を待つ操作、この場合はsleep)です。待機中はGILが解放されるため、この間に他のスレッドが実行できるようになります。つまり、PythonにGILがあってもIOバウンドのタスクではスレッド化によって大幅な高速化が可能なのです。

multiprocessingでマルチプロセスを操作する

Pythonのmultiprocessingモジュールは、プロセスを作成でき、ローカルおよびリモートの同時実行を提供します。プロセスとはプログラム(Pythonインタプリタなど)のインスタンスであり、システム内でタスクを実行するものです。multiprocessingモジュールはPythonの複数スレッドの実行を制限するGIL (Global Interpreter Lock)を克服するのに有効です。

from multiprocessing import Process

def print_numbers():
    for i in range(5):
        print('Number:', i)

def print_hello():
    for _ in range(5):
        print('Hello')

if __name__ == '__main__':
    process1 = Process(target=print_numbers)
    process2 = Process(target=print_hello)

    process1.start()
    process2.start()

    process1.join()
    process2.join()

上記のコードでは別々のプロセスで実行される2つの関数print_numbersprint_helloを定義しています。

プロセス間のデータ共有

プロセス間のデータ共有はスレッディングとは異なる方法で行われます。multiprocessingモジュールでは、プロセス間でデータを共有するためにValueArrayを用意しています。以下は簡単な例です。

from multiprocessing import Process, Value

def add_100(number):
    for _ in range(100):
        number.value += 1

if __name__ == '__main__':
    shared_number = Value('i', 0)

    process1 = Process(target=add_100, args=(shared_number,))
    process2 = Process(target=add_100, args=(shared_number,))

    process1.start()
    process2.start()

    process1.join()
    process2.join()

    print(shared_number.value)

両方のプロセスがアクセスし変更できる整数を保存するために共有されたValueを使用しています。

プールを使ってプロセスを管理する

multiprocessingでは、プロセス間の通信経路としてQueuePipeの2種類、プロセス作成APIとしてProcessPoolの2種類をサポートしています。Poolはワーカーのプールで使用するプロセスを一定数作成したい場合に使用します。以下は簡単な例です。

from multiprocessing import Pool

def square(number):
    return number * number

if __name__ == '__main__':
    numbers = [1, 2, 3, 4, 5]

    with Pool() as p:
        results = p.map(square, numbers)
        print(results)

このコードでは、ワーカープロセスのプールを作成し、map関数を使って関数とイテラブルを各プロセスにマッピングしています。

concurrentで非同期実行する

Pythonのconcurrent.futuresモジュールは、非同期で実行される関数のための高レベルのインターフェイスを提供します。このモジュールは、非同期I/O、タスクスケジューリング、プロセスプール、スレッドプールを実装しています。シンプルかつ使いやすいAPIでスレッドやプロセスを使ってタスクを同時実行できます。

以下に、簡単な使用例を示します。

from concurrent.futures import ThreadPoolExecutor
import time

def task(message):
    time.sleep(2)
    return message

pool = ThreadPoolExecutor(max_workers=5)

future = pool.submit(task, ("Completed Task"))
print(future.result())

このコードでは、ThreadPoolExecutorを使ってワーカーのプールを作成し、このプールにタスクを投入してFutureインスタンスを返します。future.result()は、タスクが完了するまでブロックしてから結果を返します。

map関数を使う

map関数はリストなどの反復可能な項目のすべてに関数を適用して、その結果のリストを返す組み込み関数です。concurrent.futuresでも利用可能で、同じ概念を適用しますが同時並行的に実行されます。

from concurrent.futures import ThreadPoolExecutor

def task(n):
    return n * 2

with ThreadPoolExecutor(max_workers=4) as executor:
    results = executor.map(task, [1, 2, 3, 4, 5])

for result in results:
    print(result)

このコードでは、map関数がリストの各項目にタスク関数を同時に適用しています。

ProcessPoolExecutorを使う

CPUに負荷のかかるタスクを実行する必要がある場合、PythonのスレッドはGILの影響を受けるため、マルチスレッドではなくマルチプロセシングを使用する方がよいです。concurrent.futuresモジュールはこのためにProcessPoolExecutorクラスを提供します。

from concurrent.futures import ProcessPoolExecutor

def task(n):
    return n * 2

with ProcessPoolExecutor(max_workers=4) as executor:
    results = executor.map(task, [1, 2, 3, 4, 5])

for result in results:
    print(result)

このコードは、ThreadPoolExecutorを使った前の例と同様に動作しますが、スレッドの代わりにプロセスを使用し、複数のCPUやコアを利用してGILによる制限を回避できます。

subprocess

Pythonのsubprocessモジュールは、新しいプロセスを生成し、その入力/出力/エラーパイプに接続し、その結果をコードを取得できる強力なツールです。os.system, os.spawn, os.popenなど、いくつかの古いモジュールや関数を置き換えることを意図しています。

以下に基本的な使い方の例を示します。

import subprocess

# UNIXコマンド'ls'を実行するための新しいプロセスを起動
process = subprocess.run(['ls'], stdout=subprocess.PIPE)

# 結果を表示
print(process.stdout.decode())

subprocess.run()関数は引数のリストを受け取ります。リストの最初の項目はコマンドで、残りの項目はコマンドのパラメータです。この場合、コマンドlsはパラメータを持ちません。

エラー処理とプロセス通信

subprocessは失敗することがあります。エラーをコードで正しく処理することが重要です。subprocessが失敗すると0以外の完了ステータスが返されます。check=True引数をsubprocess.run()関数に渡すと、subprocessで失敗したときに例外を発生させることができます。

import subprocess

try:
    subprocess.run(['ls', 'non_existent_file'], check=True)
except subprocess.CalledProcessError:
    print("'ls'コマンドが失敗しました")

このスクリプトは存在しないファイルのリストを作成しようとします。lsコマンドは失敗し、0以外の完了ステータスを返すため、subprocess.run()CalledProcessError例外を発生させています。

より複雑なユースケースでPopenを使う

より複雑なユースケースにはPopenクラスを使用できます。このクラスはより柔軟で、新しいプロセスを起動し、その入力/出力/エラーパイプへ接続するために使用できます。これは入出力データが大きすぎてメモリに収まらない場合や、プロセスの実行中に対話する必要がある状況で有用です。

import subprocess

# 新しいプロセスを起動
process = subprocess.Popen(['grep', 'python'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

# プロセスに入力値を送る
stdout, _ = process.communicate(b'pythonたのしい\njavaもたのしい\n')

# 結果を出力
print(stdout.decode())

このスクリプトは、grepプロセスを生成し入力値を送っています。grepコマンドはpythonという単語を含んでいない行をフィルタリングします。

queueでキューを操作する

queueは複数のスレッド間で安全に情報をやり取りする必要があるスレッドプログラミングにおいて、特に有用なマルチプロデューサー/マルチコンシューマーキューを実装しています。基本的なqueueはFIFO(First In, First Out)動作を提供します。

以下は、キューを使用する簡単な例です。

import queue

# 新しいキューを作成
q = queue.Queue()

# キューに要素を追加
q.put('apple')
q.put('banana')
q.put('cherry')

# キューから要素を削除
print(q.get())  # 'apple'
print(q.get())  # 'banana'

このコードでは、まずqueue.Queue()を使って新しいキューを作成します。次にput()メソッドでキューに要素を追加します。最後にget()メソッドで要素を削除して出力します。

queueのメソッドとプロパティ

queueモジュールのQueueクラスにはいくつかの便利なメソッドとプロパティがあります。put()get()の他に、empty()full()qsize()メソッドを提供しています。

import queue

q = queue.Queue(2)  # サイズが2のキューを作成

print(q.empty())  # キューが空の場合はTrue

q.put('apple')
print(q.full())  # キューのサイズが満杯ではないのでFalse
q.put('banana')
print(q.full())  # キューのサイズが満杯なのでTrue

print(q.qsize())  # キューのサイズ確認

上のコードではQueue()コンストラクタに最大サイズが与えられています。empty()はキューが空かどうか、full()はキューがいっぱいかどうかをチェックし、qsize()はキューの現在の大きさを返します。

スレッドでキューを使う

queueはスレッドと同時に実装することが多いです。以下の例では、アイテムをキューに入れるプロデューサースレッドと、キューからアイテムを取得するコンシューマースレッドを生成しています。

import queue
import threading

def producer(q):
    for i in range(5):
        q.put(i)
        print(f'Produced: {i}')

def consumer(q):
    while True:
        item = q.get()
        print(f'Consumed: {item}')
        q.task_done()

q = queue.Queue()

t1 = threading.Thread(target=producer, args=(q,))
t2 = threading.Thread(target=consumer, args=(q,))

t1.start()
t2.start()

q.join()  # すべてのタスク完了までブロックする

このコードではproducer()関数がアイテムをキューに入れ、consumer()関数がキューからアイテムを取得します。q.join()メソッドはキュー内のすべてのアイテムが取得され処理されるまでブロックされます。

asyncioで並列実行する

Pythonのasyncioライブラリは標準ライブラリの一部です。コルーチンを使ってシングルスレッドの並行コードを書いたり、ソケットや他のリソースでのI/Oアクセスを多重化したり、サブプロセスのネットワークを管理するインフラを提供します。スレッドやプロセスを使うよりも読みやすく、理解しやすい非同期コードを書くことができるようになります。

ここではasyncioを使ってタスクを並行して実行する簡単な例を紹介します。

import asyncio

async def hello():
    print('Hello,')
    await asyncio.sleep(1)
    print('world!')

# イベントループを作成
loop = asyncio.get_event_loop()

# hello関数を2回並行実行
loop.run_until_complete(asyncio.gather(hello(), hello()))

# ループを閉じる
loop.close()

このコードでは両方のタスクからHello,と表示され、1秒待って両方のタスクからWorld!と表示されます。

コルーチンとタスクの基本

asyncioの核となるのはコルーチンです。コルーチンはPythonのジェネレータ関数に特化したもので、returnへ達する前に実行を中断し、間接的に別のコルーチンへしばらく制御を渡すことができます。

タスクはコルーチンを同時にスケジュールする状況で使用されます。タスクが作成されるとすぐ実行されるようにスケジュールされます。

以下はその例です。

import asyncio

async def count():
    print("One")
    await asyncio.sleep(1)
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count())

asyncio.run(main())

この例では非同期関数count()を定義し、asyncio.gather()を使ってmain()関数内で3回同時実行しています。

高度なasyncioの機能

asyncioでは、サーバーやクライアントの作成、ロックやセマフォの管理など、高度な機能もサポートされています。たとえば、次のような簡単なエコーサーバーを作成できます。

import asyncio

async def echo(reader, writer):
    data = await reader.read(100)
    message = data.decode()
    addr = writer.get_extra_info('peername')

    print(f"Received {message} from {addr}")

    print(f"Send: {message}")
    writer.write(data)
    await writer.drain()

    writer.close()

async def main():
    server = await asyncio.start_server(echo, '127.0.0.1', 8888)

    addr = server.sockets[0].getsockname()
    print(f'Serving on {addr}')

    async with server:
        await server.serve_forever()

asyncio.run(main())

このコードではポート8888でlocalhostサーバを起動し、受信したデータをすべてエコーバック(ユーザーに対し状態を表示すること)するサーバーを定義しています。サーバーはasyncio.start_server()で起動し、例えばKeyboardInterruptなどで停止するまで動作します。

sslで安全に通信する

デジタル時代の今日、データや通信の安全性を確保することは最も重要なことです。そこで登場するのがSSL(Secure Sockets Layer)です。SSLはネットワークに接続されたコンピュータ間で認証され、暗号化されたリンクを確立するためのプロトコルです。Pythonは標準ライブラリにsslモジュールを提供しており、これは安全なソケット通信するためのソケットオブジェクトのTLS/SSLラッパーです。

import ssl
import socket

context = ssl.create_default_context()
with socket.create_connection(('www.python.org', 443)) as sock:
    with context.wrap_socket(sock, server_hostname='www.python.org') as ssock:
        print(ssock.version())

上記のコードではssl.create_default_context()関数を使用して、プロトコル、証明書など、SSLのデフォルト設定をしています。次にsocket.create_connection()を使用して、ポート443のホストwww.python.orgへの接続を作成します。context.wrap_socket()は通常のソケットをSSLでラップするために使用されます。

sslモジュールの使用例

基本的な接続を設定するだけでなく、sslモジュールはSSL関連のタスクを処理するための多くの機能性を提供してくれます。例えば、このモジュールを使ってSSLクライアントとサーバーの両方を作成できます。プロトコルや暗号など、様々なパラメータを要件に応じて指定できます。

import ssl
import socket

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations('ca_certs')

with socket.create_connection(('www.python.org', 443)) as sock:
    with context.wrap_socket(sock, server_hostname='www.python.org') as ssock:
        print(ssock.version())

上記のコードではssl.SSLContext()を使用して、特定の設定を持つSSLコンテキストを作成しています。新しいコンテキストで使用するSSLバージョンとして、ssl.PROTOCOL_TLSv1_2を設定しています。また、証明書を要求する検証モードにはssl.CERT_REQUIREDをセットしています。他のピアの証明書を検証するために使用するCA(認証局)証明書のセットを読み込むにはcontext.load_verify_locations('ca_certs')をセットします。

sslモジュールを使う有用性

sslモジュールの使い方を学ぶことでアプリケーションの安全性を確保できるため大きなメリットがあります。PythonでSSLを理解し管理することは、上記で示したように比較的簡単です。

import ssl
import urllib.request

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations('ca_certs')

https_handler = urllib.request.HTTPSHandler(context=context)
opener = urllib.request.build_opener(https_handler)
urllib.request.install_opener(opener)

response = urllib.request.urlopen('https://www.python.org/')
print(response.read())

この例ではsslモジュールを使ってコンテキストを作成し、それをPythonのurllib.requestで使って安全なHTTPSリクエストを作成しています。この例ではsslを他のPythonモジュールと組み合わせて使用することで、安全な接続できることを示しています。

signalでプロセス送受信を操作する

信号処理は信号の操作と分析を含む広大で魅力的なテーマです。コンピュータの文脈では、シグナルとはあるイベントが発生したことをプロセスに通知するものです。Pythonのsignalモジュールを使うとプログラムでシグナルを使ったり扱ったりできます。シグナルハンドラを設定したり、シグナルを無視したりするために使用されるPythonのライブラリの不可欠な部分です。

import signal
import time

def signal_handler(signum, frame):
    print('Signal handler called with signal', signum)

signal.signal(signal.SIGINT, signal_handler)

while True:
    time.sleep(1)

上記のコードでは、シグナルを処理するための関数signal_handlerを定義しています。そしてこの関数をSIGINT(通常はControl+Cで発生する)のハンドラとしてsignal.signal()を使って登録しています。このプログラムを実行し、Control+Cを押すと、プログラムが終了するのではなくシグナルハンドラが呼び出されます。

Signalモジュールの使用例

signalモジュールは単にハンドラを設定するだけではありません。シグナルを送信したり、シグナルを受信するまでプログラムの実行を一時停止したり、アラームシグナルを管理したりとさまざまな用途に使用できます。

import signal
import time

def signal_handler(signum, frame):
    print('Signal handler called with signal', signum)

signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(5)

while True:
    time.sleep(1)

この例ではSIGALRMを処理するシグナルハンドラを登録しています。次にsignal.alarm(5)を使用して、5秒後にプロセスへ送信されるアラームシグナルをスケジュールしています。シグナルを受信するとハンドラが起動されます。

Signalモジュールを使うメリット

signalモジュールはプログラムの流れを制御し、システムイベントに反応する新しい方法を開きます。これは、非同期タスク、タイムアウト、特定の条件下でのプログラムの実行の中断を扱うときに重要です。Pythonプログラマーなら誰でも知っておくべき強力なツールです。

import signal
import sys

def exit_gracefully(signum, frame):
    print("Exiting gracefully...")
    sys.exit(1)

signal.signal(signal.SIGINT, exit_gracefully)

while True:
    pass

この最後の例ではSIGINTを受信したときにプログラムを優雅に終了させるハンドラーを登録します。突然プログラムを終了させるのではなく、プログラムが終了する前にクリーンアップする方法を提供しています。これはsignalモジュールを使用して、予期せぬイベントをエレガントに処理する堅牢なアプリケーションを構築する方法の基本例です。

jsonでJSONデータを操作する

JSON(JavaScript Object Notation)形式は、そのコンパクトさと読みやすさからデータ交換のためにWeb上で広く使用されています。Pythonはjsonモジュールを使うことでJSONデータを扱うことができるようになります。json.dumps()メソッドでPythonオブジェクトをJSON文字列に変換(シリアライズ)し、json.loads()でJSONデータをオブジェクトにデコード(デシリアライズ)できます。

import json

# Pythonの辞書型
data = {
  "name": "John",
  "age": 30,
  "city": "New York"
}

# JSONへ変換
json_data = json.dumps(data)
print(json_data)

上記の例ではPython辞書をjson.dumps()メソッドでJSON文字列に変換しています。出力はJSON形式の文字列となります。

JSONでファイルを操作する

jsonモジュールにはJSONデータをファイルへ読み書きするためのメソッドも用意されています。json.dump()関数はPythonオブジェクトをJSONとしてファイルに書き込み、json.load()はJSONファイルをPythonオブジェクトに読み返します。

import json

# Pythonの辞書型
data = {
  "name": "John",
  "age": 30,
  "city": "New York"
}

# JSONデータ書き込み
with open('data.json', 'w') as f:
    json.dump(data, f)

# JSONデータ読み込み
with open('data.json', 'r') as f:
    data = json.load(f)

print(data)

ここではまずjson.dump()を使ってPython辞書をファイルdata.jsonに書き込みます。次に同じファイルを開き、json.load()を使ってデータをPythonオブジェクトに読み返します。

JSONを扱うメリット

JSONデータを扱えることは特にAPIやWebアプリケーションを扱うプログラマーにとって重要なスキルです。Pythonのjsonモジュールを使えば、JSONデータの解析やPythonのデータ構造のJSONへの変換が簡単にできます。辞書やリストだけでなく、文字列、数値、ブーリアン値、None、さらに複雑な型もサポートしており、Pythonの武器として汎用性の高いツールを提供します。

import json

# 複雑なオブジェクト
data = {
  "name": "Taro",
  "age": None,
  "married": True,
  "divorced": False,
  "children": ("Hanako", "Jiro"),
  "pets": None,
  "cars": [
    {"model": "Mazda", "mpg": 27.5},
    {"model": "Toyota", "mpg": 24.1}
  ]
}

# JSONへ変換
json_data = json.dumps(data)
print(json_data)

最後の例ではより複雑なPythonオブジェクトがJSON文字列に変換されています。このようにPythonのjsonモジュールは強力で直感的に使うことができます。

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

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

関連するコンテンツ