- Pythonであまり広く知られていない高度な機能14選を、実際の例とともに紹介
typing、generics、protocols、context managers など、静的タイピングと構造的設計について深く解説
- Python 3.10以降で新たに導入された構造的パターンマッチングや、slots、メタクラスなどのパフォーマンス最適化手法も含む
f-string、cache、future、proxy、for-else、walrus など、読みやすいコードを書くためのヒントを収録
- 各機能ごとに追加学習のためのリンクと参考資料を提供し、ジュニア開発者でも取り組みやすい構成
Pythonの高度な機能14選まとめ
# 型オーバーロード
@overload デコレータを使うと、1つの関数に複数の型シグネチャを定義できる
- 型チェッカーは渡された引数の値に応じて、戻り値の型を正確に推論できる
Literal を活用して文字列値の制約も可能
id または username のどちらか一方だけを必須にする関数シグネチャも実装できる
- 型安全性のための軽量な Enum 代替として
Literal を活用できる
# キーワード専用 / 位置専用引数
* を使うとキーワード専用引数に設定可能(位置引数としては使えない)
/ を使うと位置専用引数に設定可能(キーワード引数としては使えない)
- API設計時に引数の使い方を明確に強制できる
# Futureアノテーション (__future__)
- 型ヒントは本来ランタイムで即時評価されるため、宣言順の問題が発生する
from __future__ import annotations により、評価時点を遅らせることができる
- ただし文字列として処理される方式のため、ランタイムで型を使う場合は注意が必要
PEP 649 は __annotations__ 属性に対して遅延評価方式への改善を提案している
# ジェネリック(Generic)構文
- Python 3.12から、新しいジェネリック型定義構文をサポート
TypeVar の代わりに class Foo[T, U: int] 形式で、より直感的に使える
- 可変長ジェネリック(Variadic Generics) も導入され、さまざまな型を扱える
- 型エイリアスの定義も簡潔になり、
type Vector = list[float] 形式で使える
# プロトコル(Protocols)
- Duck Typingの型チェック版として、構造的サブタイピングを実現できる
- クラスが特定のメソッドを持っていれば、型継承がなくても型互換を持たせられる
@runtime_checkable によって isinstance チェックも可能に拡張できる
# コンテキストマネージャ(Context Manager)
__enter__、__exit__ メソッドを持つオブジェクトとして with ブロックで使用する
contextlib.contextmanager デコレータにより、シンプルな関数ベース実装も可能
yield を境に前後で設定とクリーンアップ処理を行う
# 構造的パターンマッチング
match-case 構文により、複雑なデータ構造を直感的に分岐処理できる
- タプル / リストの分解、ORパターン、ガード条件(if)、ワイルドカードが使える
- データの構造を基準に分岐できるため、可読性と保守性が向上する
# __slots__ 最適化
__dict__ の代わりに固定スロットを使うことで、メモリと速度を最適化
__slots__ では属性名だけを指定したタプルを使う
- クラスへの不要な属性追加を防げる
- ただしマイクロ最適化の範囲なので、利用には慎重さが必要
# Pythonコードスタイルのヒント集
- for-else構文: ループが
break なしで終了した場合に else を実行
- ウォルラス演算子(
:=): 変数代入と条件判定を同時に行える
- orの短絡評価: 複数の値のうち最初に真となる値を返す
- 比較演算子の連鎖:
0 < x < 10 のようにコードを簡潔にできる
# f-stringの高度なフォーマット
f"{変数=}" 構文により、デバッグ用の表現が可能
- 数値フォーマット(
:.2f, :+.2f, :,)、日付フォーマット(%Y-%m-%d) など多様なオプション
- 中央揃え、パディング、パーセンテージ表現など、フォーマットミニ言語を活用できる
# キャッシュデコレータ
@lru_cache と @cache により、関数の結果を保存して高速化できる
- 再帰関数や反復計算が多い場合に有用
@cache はPython 3.9から導入され、デフォルトで無制限キャッシュを提供する
# Python Future
- JSのPromiseに似た非同期オブジェクト処理機能
Future.set_result()、add_done_callback() などで結果を非同期に管理
asyncio.Future() は await とともに使用できる
ThreadPoolExecutor と組み合わせると、バックグラウンド並列処理も可能
# プロキシプロパティ (Proxy Property)
- 1つのクラス属性を属性としても、関数としても動作させられる
__get__、__call__、__repr__ により2つの機能を提供
- API設計時にデフォルト値と引数付き呼び出しを1つの方法で扱うことができる
- 実運用というよりは、実験的な例として参考になる
# メタクラス
- クラスそのものを生成するクラスのクラス
- クラス属性の操作や自動登録などのメタロジックを実装できる
- 現実的には多くの場合、デコレータで代替可能
- Django、SQLAlchemy、Pydantic などでは内部的にメタクラスを活用している
5件のコメント
バックエンドの観点では、メタクラスはデバッグを難しくするという経験がありました。
for-elseは可読性や明確さが高くないという意見があり、アンチパターンと見なされることが多く、asyncio.Futureはasyncioの内部的な実装ディテールとして扱われる点に注意してください。ありがとうございます。特に10番はすぐに取り入れます。
AIコーディングルールも追加します..
役立つヒントをありがとうございます
Hacker Newsのコメント
こんにちは! ブログの原著者です! 午前4時に自分の記事がHNのフロントページに載っているのを見て驚きました
Pythonを使うたびに、コードがPythonを間違って使っているように見えないか心配になります
PythonはPythonのままであるべきで、golang、Rust、Typescriptはそれぞれ独自の哲学と設計を持つべきです
Pythonの最大の長所は、実行可能な擬似コードのように感じられることです
9.3の段落の評価についての指摘: 空文字列がある場合、評価のされ方が異なります
Javascript/TypescriptからPythonに移った者として、有用なリソースです
ほとんどの機能は高度な機能ではありません
この一覧で変えたいのは、collections.abcコンテナが含まれていることです
この記事を読むのは楽しかったです