mcpField
P
python-refactor

python-refactor

github.com/acaprino開発9272 回インストール1 日前に更新
リポジトリ

python-refactor について

python-refactorは、動作を維持しながらPythonコードの明瞭さと保守性を高めるリファクタリング用スキルです。レガシーコードや保守しにくいコードに取り組む開発者向けに、移行の安全策、静的解析、テスト、複雑度検査を含む段階的な手順を示します。

主な機能

  1. 01段階的なリファクタリング手順
  2. 02破壊的変更の安全チェックリスト
  3. 03静的解析とテストによる検証
  4. 04複雑度と保守性の指標
  5. 05Pythonリファクタリングパターンの案内
  6. 06性能リグレッションの確認

活用シーン

  1. 01レガシーPythonモジュールの再構成
  2. 02複雑な関数やネストの削減
  3. 03散在する関数とグローバル状態の整理
  4. 04リファクタリング中の動作検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/acaprino/daodan --skill python-refactor

インストール後、Claude Code で/python-refactorを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
pyproject.toml
assets/templates/
analysis_template.md
flake8_report_template.md
summary_template.md
references/
anti-patterns.md
cognitive_complexity_guide.md
flake8_plugins_guide.md
oop_principles.md
patterns.md
REGRESSION_PREVENTION.md
references/examples/
python_complexity_reduction.md
script_to_oop_transformation.md
typescript_naming_improvements.md
scripts/
analyze_multi_metrics.py
analyze_with_flake8.py
benchmark_changes.py
check_documentation.py
compare_flake8_reports.py
compare_metrics.py
measure_complexity.py

詳細

Python のリファクタリング

正確性を維持しながら、複雑な Python コードを明快で保守しやすいコードに変換します。安全性を設計に組み込んだ、段階的なワークフローと継続的な検証を行います。詳細な参考資料(アンチパターン、OOP の原則、認知的複雑度、回帰の防止)については、references/ ディレクトリを参照してください。

呼び出すタイミング

  • 「人間にとって読みやすく」「読みやすい」「保守しやすい」「クリーンに」「リファクタリング」と明示的に依頼された場合
  • コードレビューで、理解しにくさや保守性の問題が指摘された場合
  • レガシーコードのモダナイゼーション
  • オンボーディング/教育の場面
  • 複雑度の指標がしきい値を超えている場合
  • 警告サイン:ファイルが 500 行を超え、関数が散在してグローバル状態を使用している、global 文が複数ある、モジュール/クラスの明確な構成がない、設定がビジネスロジックに混在している

呼び出してはいけない場合

  • パフォーマンスが重要で、プロファイリングの結果、まずパフォーマンス最適化が必要だと分かった場合
  • コードの削除または置き換えが予定されている場合
  • 外部依存関係について、上流プロジェクトへの貢献が代わりに必要な場合
  • ユーザーが読みやすさよりパフォーマンス最適化を明示的に優先した場合

基本原則(優先順位順)

  1. 複雑なコードには構造化された OOP を優先する -- 共有状態、複数の関心事、散在するグローバル変数がある場合は、クラス/モジュールに再構成します。(ただし、純粋関数を使う単純なモジュール、click/argparse の CLI、関数型パイプラインを無理にクラス化する必要はありません。)
  2. 巧妙さより明快さを優先する -- 暗黙的な処理より明示的な処理を優先します
  3. 正確性を維持する -- すべてのテストに合格し、動作が同一であること
  4. 単一責任 -- クラス/関数ごとに役割を 1 つにする(SOLID)
  5. 構造で自己説明する -- コードは何をするか、コメントはなぜそうするかを示します
  6. 段階的に情報を開示する -- 複雑さを段階的に明らかにします
  7. 妥当なパフォーマンス -- 明示的な承認なしに 2 倍を超える性能低下を許容しません

厳守事項

  • 安全性を設計に組み込む -- 破壊的な変更には、移行チェックリストが必須です。CREATE → SEARCH → MIGRATE → VERIFY の順に進め、その後にのみ REMOVE します。移行が 100% 検証される前に削除してはいけません。
  • 静的解析を最初に実施する -- テストの前に flake8 --select=F821,E0602(または ruff check --select=F821)を実行します。これにより、NameError をすぐに検出できます。
  • 動作を維持する -- 既存のテストすべてに合格すること。
  • パフォーマンスの回帰を起こさない -- 明示的な承認なしに 2 倍を超える性能低下を許容しません。
  • API を変更しない -- 明示的に依頼され、かつ文書化されている場合を除き、パブリック API は変更しません。
  • 過剰設計をしない -- 単純なものは単純なままにします。
  • マジックを使わない -- フレームワークのマジックやメタプログラミングは、絶対に必要な場合を除き使用しません。
  • 継続的に検証する -- 論理的な変更ごとに、静的解析とテストを実施します。

回帰の防止(必須)

リファクタリングによって回帰を絶対に引き起こしてはいけません。 セッションを始める前に references/REGRESSION_PREVENTION.md を読んでください。

各セッションの前に:

  • テストスイートが 100% 合格していること
  • 対象コードのカバレッジが 80% 以上であること(満たない場合は、先にテストを作成します)
  • 重要なエッジケースのゴールデン出力を取得していること
  • 静的解析のベースラインを保存していること

各マイクロ変更の後(最後にまとめてではなく、変更を 1 つ行うたびに):

  • flake8 --select=F821,E999 → エラー 0 件
  • pytest -x → すべて合格
  • エッジケースを 1 つ抜き取り、動作に変更がないことを確認

いずれかのチェックに失敗した場合:停止 → 元に戻す → 分析 → アプローチを修正 → 再試行。

回帰が 1 つでもあれば、全面的な失敗です。

ワークフロー(4 フェーズ)

フェーズ 1:分析
  1. コードベースの対象箇所をすべて読みます。
  2. references/anti-patterns.md を使って、可読性の問題を特定します(スクリプトのような構成/グローバル状態、God Object、ネストした条件分岐、長い関数、マジックナンバー、難解な名前)。
  3. references/oop_principles.md に照らして、アーキテクチャを評価します(適切なクラス/モジュール、状態のカプセル化、責任の分離、SOLID、ハードコードされた依存関係に対する DI)。
  4. scripts/measure_complexity.py または scripts/analyze_multi_metrics.py を使って、現在の指標を測定します。
  5. リント解析を実行します(以下のツールを参照)。
  6. テストカバレッジを確認し、リファクタリングの前に補うべき不足箇所を特定します。
  7. assets/templates/analysis_template.md を使って文書化します。

出力:影響度とリスクに基づいて優先順位を付けた問題の一覧。

フェーズ 2:計画
  1. 変更ごとに分類します:
    • 非破壊的(名前変更、ドキュメント、型ヒント)→ 低リスク
    • 破壊的(グローバル変数の削除、関数の削除、API の置き換え)→ 高リスク
  2. 破壊的な変更には、移行計画が必須です:
    • 削除対象の各要素の使用箇所をすべて検索します
    • 使用箇所をすべて記録します(ファイル、行、種類)
    • 完全な移行計画がなければ、破壊的な変更には着手できません
  3. 変更ごとにリスクを評価します(低/中/高)
  4. 依存関係をマッピングします。このコードに依存しているものは何ですか?
  5. テスト戦略を策定します。必要なテストは何ですか?何が壊れる可能性がありますか?
  6. 変更を最も安全なものから最もリスクの高いものへと並べます
  7. 期待される指標の改善を記録します

出力:リファクタリング計画、順序付けした変更、移行計画、テスト戦略、ロールバック計画。

フェーズ 3:実行
非破壊的な変更(いつでも安全)
  1. わかりやすい名前に変更します
  2. マジックナンバー/文字列を名前付き定数に抽出します
  3. ドキュメントと型ヒントを追加・改善します
  4. ガード節を追加してネストを減らします
破壊的な変更(厳格なプロトコル)
  1. 新しい構造を作成します(削除はしません)。新しいクラス/関数とテストを記述します
  2. 削除対象の要素の使用箇所をすべて検索します
  3. 見つかった使用箇所をすべて記録した移行チェックリストを作成します
  4. 使用箇所を一つずつ移行し、リストをチェックしながら、各移行後に静的解析とテストを実行します
  5. 移行が完了していることを検証します。検索を再実行し、古い参照が一つも見つからないことを確認します
  6. 100%の移行が確認できてから、古いコードを削除します
実行ルール
  • 破壊的な変更では、移行チェックリストを絶対に省略しないでください
  • テストの前に静的解析を実行します
  • 一度に一つのパターンのみを扱います。一つの変更に複数のリファクタリングパターンを混在させないでください
  • アトミックコミットを行います。各移行ステップを個別にコミットします
  • いかなるエラー(静的解析またはテストの失敗)が発生しても停止し、ただちに修正または差し戻しを行います
推奨順序
  1. スクリプトのようなコードを適切なアーキテクチャに変換します(references/examples/script_to_oop_transformation.md)
  2. わかりやすい名前に変更します
  3. マジックナンバー/文字列を定数/列挙型に抽出します
  4. ドキュメントと型ヒントを改善します
  5. メソッドを抽出して関数の長さを短くします
  6. ガード節を使って条件分岐を簡素化します
  7. ネストの深さを減らします
  8. 最終レビュー:関心事の分離
フェーズ 4:検証
  1. 最初に静的解析を実行します:
    flake8 <file> --select=F821,E0602          # undefined names/variables -- MUST be 0
    flake8 <file> --select=F401                # unused imports
    flake8 <file>                              # full quality check
    
  2. テストスイート全体を実行します。100%の合格が必須です。
  3. アーキテクチャの検証:グローバル状態を排除/カプセル化し、適切なモジュール/クラスを使用し、責務を分離し、SOLID 原則に準拠します。
  4. scripts/measure_complexity.py または scripts/analyze_multi_metrics.py を使って、変更前後の指標を確認します。
  5. ホットパスについて、scripts/benchmark_changes.py を使ってパフォーマンスのリグレッションを確認します。
  6. assets/templates/summary_template.md を使ってサマリーレポートを作成します。
  7. 次の場合は人によるレビューが必要であることを明示します:パフォーマンスが 10%を超えて低下した場合、公開 API のシグネチャが変更された場合、テストカバレッジが低下した場合、アーキテクチャに大幅な変更があった場合。

リファクタリングパターン(カタログの概要)

例を含むカタログ全体は references/patterns.md にあります。主なパターン:

  • ガード節 — ネストした条件分岐の代わりに早期リターンを使います
  • メソッドの抽出 — 大きな関数を、役割を絞った単位に分割します(ネストカウンターをリセットします。認知的複雑度に最も効果的です)
  • 辞書によるディスパッチ — if-elif の連鎖をルックアップテーブルに置き換えます
  • Match 文(Py 3.10+)— 分岐ごとではなく、合計で +1 として数えます
  • 名前付きブール条件 — 複雑なブール式を名前付き変数に抽出します
  • グローバル状態のカプセル化 — グローバル変数を適切にカプセル化したクラスに移します
  • 関連する関数のグループ化 — 散在する関数を、責務ごとにクラスにまとめます
  • ドメインモデルの作成 — プリミティブな dict を dataclass と enum に置き換えます
  • 依存性注入の適用 — ハードコードされた依存関係を、注入される依存関係に置き換えます

認知的複雑度の計算ルールと削減方法については、references/cognitive_complexity_guide.md を参照してください。

命名規則
  • 変数:説明的な名前にします。ブール値には is_active / has_permission / can_edit を使い、コレクションには複数形を使います。
  • 関数:動詞 + 目的語にします(calculate_total、validate_email)。ブール値を返すクエリには is_valid() / has_items() を使います。
  • 定数:UPPERCASE_WITH_UNDERSCORES を使い、マジックナンバーやマジックストリングは置き換えます。
  • クラス:PascalCase の名詞にします(UserAccount、PaymentProcessor)。

修正すべきアンチパターン(優先順位順)

カタログ全体:references/anti-patterns.md。

  • 重大:グローバル状態を持つスクリプト風/手続き型コード、God Object / God Class
  • 高:複雑な入れ子の条件分岐(3 レベル超)、長い関数(30 行超)、マジックナンバー、分かりにくい名前、型ヒントの欠如、docstring の欠如
  • 中:重複コード、プリミティブ型への過度な依存、長いパラメーターリスト(5 個超)
  • 低:一貫性のない命名、冗長なコメント、未使用のインポート

ツール

主なスタック:Ruff + Complexipy(新規プロジェクトに推奨)
uv tool install ruff complexipy radon wily

ruff check src/                                 # fast linting (Rust, replaces flake8+plugins)
complexipy src/ --max-complexity-allowed 15     # cognitive complexity (Rust)
radon mi src/ -s                                # maintainability index

完全な設定(pyproject.toml、pre-commit、GitHub Actions):references/cognitive_complexity_guide.md。

代替:flake8 + 厳選プラグイン

すでに flake8 を使っているプロジェクトについては、references/flake8_plugins_guide.md(厳選された 16 個のプラグイン選択リスト)を参照してください。

複数メトリクスの分析

scripts/analyze_multi_metrics.py は、complexipy + radon + 保守性インデックスを 1 つのレポートにまとめます。

メトリクスツール用途
認知的複雑度complexipy人間による理解度
循環的複雑度ruff(C901)、radonテスト計画
保守性インデックスradonコード全体の健全性
メトリクスの目標値
  • 循環的複雑度:関数あたり < 10(警告 15、エラー 20)
  • 認知的複雑度:関数あたり < 15(SonarQube のデフォルト値、警告 20)
  • 関数の長さ:< 30 行(警告 50)
  • 入れ子の深さ:≤ 3 レベル
  • docstring のカバレッジ:公開関数の > 80%
  • 型ヒントのカバレッジ:公開 API の > 90%
Wily による履歴追跡

しきい値だけでなく、傾向も重要です。セットアップと CI の統合については、references/cognitive_complexity_guide.md を参照してください。

よくあるリファクタリングのミス

ガイド全文:references/REGRESSION_PREVENTION.md。主な注意点:

  1. 移行の未完了 -- すべての使用箇所の移行前に古いコードを削除すること(NameError の原因になります)。
  2. パターンの部分的な適用 -- 一部の関数にだけリファクタリングを適用すること。
  3. 公開 API の破壊 -- 外部コードで使われているシグネチャを変更すること。
  4. テストですべて確認できると思い込むこと -- テストは通っても実行時エラーが発生します(静的解析を実行してください!)。

ツールの使い分け

  • clean-code(クロスランゲージプラグイン) -- 複数の言語にわたる外見上の整理に使います。ローカル変数の名前を変更し、コメントを改善し、構造を簡素化します。回帰リスクが最も低い方法です。「読みやすくして」「命名を整理して」といった場合に使います。
  • python-refactor(このスキル) -- Python 専用の大規模な再構成に使います。OOP への変換、SOLID、複雑度メトリクス、移行チェックリスト、ベンチマークによる検証に対応します。「このモジュールをリファクタリングして」「複雑度を下げて」「OOP に変換して」といった場合に使います。

段階的な適用手順:clean-code → python-refactor(最も安全な方法から最も徹底的な方法へ)。

統合

  • python-tdd -- リファクタリング前にテストを用意し、その後カバレッジを検証します。
  • python-performance-optimization -- リファクタリングの前後に詳細なプロファイリングを行います。
  • python-packaging -- ライブラリをリファクタリングする場合は、pyproject.toml と配布を扱います。
  • uv-package-manager -- ツールの実行には uv run ruff、uv run complexipy を使います。
  • async-python-patterns -- 非同期コードをリファクタリングするときは、非同期パターンを参照します。

リファクタリングしない場合

パフォーマンスが重要な最適化済みコード(まずプロファイルを実行)、削除が予定されているコード、外部依存関係(上流に変更を提案)、変更する必要のない安定したレガシーコード。

制限事項

アルゴリズムの複雑度は改善できません(アルゴリズムの変更が必要です)。コードやコメントにないドメイン知識は追加できません。テストなしでは正しさを保証できません。スタイルの好みはさまざまなため、チームの規約に合わせて調整してください。

例

references/examples/:

  • script_to_oop_transformation.md -- スクリプトからクリーンな OOP アーキテクチャへの変換(代表的なケーススタディ)
  • python_complexity_reduction.md -- ネストした条件分岐と長い関数
  • typescript_naming_improvements.md -- 命名パターン(言語横断の参考資料)

成功基準

  1. リグレッションゼロ -- すべてのテストが合格し、動作に変更がない
  2. ドキュメントに記載された重要なケースでゴールデンマスターと一致する
  3. 複雑度のメトリクスが改善されている(概要に記載)
  4. パフォーマンスのリグレッションが 10% を超えない(または明示的な承認がある)
  5. ドキュメントのカバレッジが向上している
  6. 人間にとってコードが読みやすくなっている
  7. 新たなセキュリティ脆弱性がない
  8. アトミックで、十分に文書化された Git 履歴
  9. Wily の傾向 -- 複雑度が前回のコミットより増加していない
  10. 静的解析で改善が確認できる

コメント