======================================================================== Python コーディング規則 (Python Coding Style Guide) ======================================================================== 1. 基本方針 (Basic Policy) ------------------------------------------------------------------------ PEP 8 を基本とし,チーム内での一貫性を最優先とする. 本規則に明記されていない事項は PEP 8 に従う. ※ 書式・記述スタイルの基準は `GUIDE_01_ドキュメント作成ガイド.txt` を参照する. 2. フォーマット (Formatting) ------------------------------------------------------------------------ 2-1. インデント ・半角スペース4つを使用する.タブ文字は使用しない. ・継続行は,開き括弧に揃えるか,ハンギングインデント(スペース4つ追加)とする. ・例: # 開き括弧に揃える result = some_function(arg_one, arg_two, arg_three, arg_four) # ハンギングインデント result = some_function( arg_one, arg_two, arg_three, arg_four, ) 2-2. 1行の最大文字数 ・79文字を上限とする(PEP 8 準拠). ・文字列やコメントが長くなる場合は,括弧による暗黙の行継続を優先する. ・バックスラッシュ `\` による行継続は極力避ける. 2-3. 空行 ・トップレベルの関数・クラス定義の間: 2行空ける. ・クラス内のメソッド定義の間: 1行空ける. ・関数内の論理的なまとまりの区切り: 1行空ける(使いすぎに注意). 2-4. 文字コード ・UTF-8 を使用する. ・エンコーディング宣言(`# -*- coding: utf-8 -*-`)は Python 3 では不要. 3. 命名規則 (Naming Conventions) ------------------------------------------------------------------------ 3-1. 一覧 ■ 変数・関数・メソッド・引数 ・スタイル: snake_case ・例: `motor_speed`,`calc_distance`,`handle_input` ■ 定数 ・スタイル: UPPER_SNAKE_CASE ・例: `MAX_SPEED`,`DEFAULT_PORT`,`PIN_MOTOR_LEFT` ■ クラス ・スタイル: PascalCase ・例: `MotorController`,`SensorReader`,`UltrasonicSensor` ■ モジュール(ファイル名) ・スタイル: snake_case ・例: `motor_controller.py`,`sensor_reader.py` ■ パッケージ(ディレクトリ名) ・スタイル: 全て小文字,アンダースコアなし(短い名前を推奨) ・例: `drivers`,`utils`,`config` ■ プライベート ・先頭にアンダースコア1つを付与する. ・例: `_internal_value`,`_calc_raw_data` 3-2. 命名の原則 ・意味のある名前を付け,略語は最小限にする. - NG: `d`,`tmp`,`val`,`calc`(単体で使用) - OK: `distance`,`temperature`,`motor_value` ・ループカウンタ等,スコープが極めて狭い場合のみ `i`,`j`,`x`,`y` を許容する. ・bool 型の変数は `is_`,`has_`,`can_` 等の接頭辞を付ける. - 例: `is_connected`,`has_obstacle`,`can_move` 4. import の規則 (Import Rules) ------------------------------------------------------------------------ 4-1. 順序 以下の順序で記述し,グループ間に1行空ける. 1. 標準ライブラリ(`os`,`sys`,`time` 等) 2. サードパーティライブラリ(`RPi.GPIO`,`numpy` 等) 3. プロジェクト内モジュール ・例: import os import sys import time import RPi.GPIO as GPIO from drivers.motor import MotorController from sensors.ultrasonic import UltrasonicSensor 4-2. スタイル ・1行に1モジュールを記述する. - NG: `import os, sys` - OK: `import os` と `import sys` を別行に記述 ・`from ... import *` は禁止する(名前空間の汚染を防ぐ). ・`from ... import` で複数の名前を取り込む場合は括弧でまとめる. from sensors.ultrasonic import ( UltrasonicSensor, TRIGGER_PIN, ECHO_PIN, ) 5. 型ヒント (Type Hints) ------------------------------------------------------------------------ 5-1. 方針 ・関数の引数と返り値には型ヒントを付与する. ・ローカル変数への型ヒントは,型が自明でない場合のみ付与する. 5-2. 書式 ・Python 3.10 以降の記法(`X | None`,`list[int]`)を使用する. ・例: def calc_distance(speed: float, duration: float) -> float: return speed * duration def find_obstacle(sensors: list[UltrasonicSensor]) -> int | None: ... 6. コーディングルール (Coding Rules) ------------------------------------------------------------------------ 6-1. 比較 ・`None` との比較は `is` / `is not` を使用する. - NG: `if value == None:` - OK: `if value is None:` ・bool 値との比較は暗黙的に行う. - NG: `if is_active == True:` - OK: `if is_active:` 6-2. 文字列 ・引用符はダブルクォート `"` で統一する. ・文字列の組み立てには f-string を使用する. - NG: `"Speed: " + str(speed)` - OK: `f"Speed: {speed}"` 6-3. 例外処理 ・裸の `except:` は禁止する.必ず例外クラスを指定する. - NG: `except:` - OK: `except ValueError:` ・`except Exception` も極力避け,具体的な例外を捕捉する. 6-4. with 文 ・ファイル操作や GPIO のクリーンアップなど,リソース管理には `with` 文を使用する. ・例: with open("config.json", "r") as f: config = json.load(f) 6-5. マジックナンバーの禁止 ・意味のある数値は定数として定義する. - NG: `time.sleep(0.5)` - OK: SENSOR_INTERVAL_SEC = 0.5 time.sleep(SENSOR_INTERVAL_SEC) 7. ファイル構成 (File Structure) ------------------------------------------------------------------------ 1つの Python ファイル内は,以下の順序で記述する. 1. ファイルドキュメント(docstring) 2. import 文 3. 定数定義 4. クラス定義 / 関数定義 5. `if __name__ == "__main__":` ブロック(必要な場合のみ) ・例: """ motor_controller モーターの制御を担当するモジュール """ import time import RPi.GPIO as GPIO from config.pins import PIN_MOTOR_LEFT, PIN_MOTOR_RIGHT MAX_SPEED = 100 DEFAULT_SPEED = 50 class MotorController: """左右のモーターを制御するクラス""" def __init__(self, left_pin: int, right_pin: int) -> None: ... def forward(self, speed: int = DEFAULT_SPEED) -> None: ... if __name__ == "__main__": controller = MotorController(PIN_MOTOR_LEFT, PIN_MOTOR_RIGHT) controller.forward() 8. ツール設定 (Tooling) ------------------------------------------------------------------------ コードの品質を自動で維持するため,以下のツールの導入を推奨する. ■ フォーマッター ・black: コードの自動整形に使用する. - 1行の最大文字数は 79 に設定する. ■ リンター ・flake8 または ruff: スタイル違反や潜在的なバグを検出する. ■ 型チェッカー ・mypy: 型ヒントの整合性を静的に検証する. ※ ツールの具体的な設定や導入手順は `ENV_` カテゴリのドキュメントに記載する.