標準ライブラリ活用
collections
from collections import namedtuple, deque, OrderedDict, ChainMap
# namedtuple: 名前付きタプル
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 10 20
# deque: 両端キュー(高速な先頭追加/削除)
d = deque([1, 2, 3])
d.appendleft(0) # [0, 1, 2, 3]
d.rotate(1) # [3, 0, 1, 2]
# deque の maxlen で固定長キュー
recent = deque(maxlen=3)
for i in range(5):
recent.append(i)
print(list(recent)) # [2, 3, 4]
functools
from functools import partial, reduce, total_ordering
# partial: 引数を部分適用
def power(base, exp):
return base ** exp
square = partial(power, exp=2)
cube = partial(power, exp=3)
print(square(5)) # 25
print(cube(3)) # 27
# reduce: 畳み込み
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda a, b: a + b, numbers)
print(total) # 15
# total_ordering: 比較メソッドを自動生成
@total_ordering
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __eq__(self, other):
return self.score == other.score
def __lt__(self, other):
return self.score < other.score
pathlib(パス操作)
from pathlib import Path
# パス操作
p = Path('/home/user/project')
print(p / 'src' / 'main.py') # /home/user/project/src/main.py
print(p.parent) # /home/user
print(p.name) # project
# ファイル検索
for py_file in Path('.').rglob('*.py'):
print(py_file)
# ファイル情報
p = Path('data.txt')
if p.exists():
print(f"サイズ: {p.stat().st_size}バイト")
print(f"拡張子: {p.suffix}")
logging(ログ出力)
import logging
# 基本設定
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s [%(levelname)s] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)
logger.debug("デバッグ情報")
logger.info("処理開始")
logger.warning("注意")
logger.error("エラー発生")
logger.critical("致命的なエラー")
typing(型ヒント)
from typing import Optional, Union
def find_user(user_id: int) -> Optional[dict]:
# Noneを返す可能性がある場合
pass
def process(data: Union[str, bytes]) -> str:
# strまたはbytesを受け取る場合
pass
# Python 3.10+
def process_new(data: str | bytes) -> str:
pass
contextlib(コンテキストマネージャ)
from contextlib import contextmanager
import time
@contextmanager
def timer(label):
start = time.perf_counter()
try:
yield
finally:
elapsed = time.perf_counter() - start
print(f"{label}: {elapsed:.4f}秒")
with timer("データ処理"):
# 時間を計測したい処理
total = sum(range(1000000))
まとめ
collections でCounter, deque, namedtuple等の特殊コンテナを使う
functools でpartial, lru_cache, reduce等の関数ツールを活用
pathlib でモダンなファイルパス操作
logging でprint文の代わりにログ出力
typing で型ヒントを付けてコードの可読性を向上