0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python:PEP 8とコーディング規則 早見表

0
Posted at

Python:PEP 8とコーディング規則

Pythonコードを読みやすく、一貫した形式で記述するための基本規則をまとめた資料です。
Python 3.11以降を想定しています。


目次

  1. PEP 8とは
  2. コーディング規則が必要な理由
  3. 命名形式の読み方
  4. 基本的な命名規則
  5. インデント・行の長さ・空行
  6. importの書き方
  7. 空白・改行・式の書き方
  8. コメントとドックストリング
  9. 推奨される比較・条件式
  10. 実行できる良い例
  11. よくある修正例
  12. 自動チェック・自動整形
  13. まとめ

1. PEP 8とは

**PEP 8(ペップ・エイト)**は、Pythonコードのスタイルガイドです。

  • PEP:Python Enhancement Proposal(パイソン・エンハンスメント・プロポーザル)
  • 8:提案番号

PEP 8では、主に次を定めています。

  • 命名方法
  • インデント
  • 行の長さ
  • 空行
  • importの並べ方
  • 空白の使い方
  • コメント
  • 読みやすい条件式

PEP 8の目的

コードは書く回数より、読まれる回数の方が多いため、読みやすさと一貫性を重視する。

絶対に機械的に守る規則なのか

PEP 8は重要な基準ですが、次の優先順位で判断します。

1. 案件・会社・チームの規約
2. 既存プロジェクトの一貫性
3. 使用フレームワークやツールの規約
4. PEP 8

既存コードとの一貫性を壊してまで、1行だけ形式を変えると読みづらくなる場合があります。

一言
PEP 8はPythonコードの読みやすさと統一感を高めるスタイルガイドで、命名・インデント・空白・行長などの基本方針を定めています。


2. コーディング規則が必要な理由

2-1. 読む人が迷いにくい

# 何を表すか分かりにくい
x = 1200

# 目的が分かりやすい
total_price = 1200

2-2. 名前から種類や役割を推測できる

class OrderService:
    pass

MAX_RETRY_COUNT = 3

def calculate_total() -> int:
    return 0
名前 推測できること
OrderService クラス
MAX_RETRY_COUNT 定数
calculate_total 関数・メソッド

2-3. レビューしやすい

書き方の違いではなく、処理内容に集中できます。

2-4. 自動ツールを利用しやすい

RuffなどのLint・整形ツールで、一定の規則を自動確認できます。


3. 命名形式の読み方

形式 読み方 特徴
snake_case スネークケース total_price 小文字を_で区切る
UPPER_SNAKE_CASE アッパー・スネークケース MAX_RETRY_COUNT 大文字を_で区切る
CapWords キャップワーズ OrderService 各単語の先頭を大文字にする
PascalCase パスカルケース OrderService PEP 8のCapWordsとほぼ同じ意味で使われる
camelCase キャメルケース totalPrice 先頭は小文字、以後の単語を大文字にする
_leading_underscore 先頭アンダースコア _internal_value 内部用であることを示す慣習
__dunder__ ダンダー __init__ Pythonが予約する特殊名

Pythonでは、クラスはCapWords、関数・変数はsnake_case、定数はUPPER_SNAKE_CASEが基本です。


4. 基本的な命名規則

まず覚える基本8分類

番号 対象 規則 良い例 避けたい例
1 モジュール 短い小文字。必要なら_ order_service.py OrderService.py
2 パッケージ 短い小文字。_はできるだけ避ける orders Order_Package
3 クラス CapWords OrderService order_service
4 例外クラス CapWords。エラーならErrorを末尾に付ける OrderNotFoundError order_not_found
5 関数・メソッド snake_case calculate_total calculateTotal
6 変数・引数 snake_case item_count ItemCount
7 定数 UPPER_SNAKE_CASE MAX_RETRY_COUNT maxRetryCount
8 型変数 短いCapWordsまたは意味のある名前 TKeyT type_variable

4-1. モジュール名

良い例
pricing.py
order_service.py
file_utils.py

避けたい例
Pricing.py
order-Service.py
file utils.py

理由:

  • import名として扱いやすい
  • OS間の大文字・小文字差による問題を減らす
  • Pythonの一般的な命名と揃う

4-2. パッケージ名

orders/
users/
shoptools/

PEP 8では、短い小文字を推奨し、アンダースコアは非推奨寄りです。ただし、実際のプロジェクトでは可読性や既存規約によりshop_toolsのような名前も使われます。

4-3. クラス名

class OrderService:
    pass


class ShippingAddress:
    pass

4-4. 例外クラス名

class OrderNotFoundError(Exception):
    """注文が見つからない場合の例外。"""

エラーを表す例外では、末尾にErrorを付けると役割が明確です。

4-5. 関数・メソッド名

def calculate_total(price: int, quantity: int) -> int:
    return price * quantity

動作を表すため、動詞から始める名前がよく使われます。

calculate_total
find_user
create_order
validate_input

4-6. 変数・引数名

unit_price = 200
item_count = 3

1文字名は、短いループや数式など範囲が限定される場合を除き、目的が分かる名前を使います。

# 範囲が短く意味が明確なら許容されやすい
for i in range(3):
    print(i)

4-7. 定数名

Pythonに言語として変更不能な定数はありませんが、変更しない値を大文字で表します。

TAX_RATE = 0.10
MAX_RETRY_COUNT = 3
DEFAULT_TIMEOUT_SECONDS = 30

4-8. 型変数名

from typing import TypeVar

T = TypeVar("T")
KeyT = TypeVar("KeyT")
ValueT = TypeVar("ValueT")

補足:selfcls

class User:
    user_count = 0

    def __init__(self, name: str) -> None:
        self.name = name

    @classmethod
    def get_user_count(cls) -> int:
        return cls.user_count
用途 第1引数
インスタンスメソッド self
クラスメソッド cls

補足:内部用の名前

def _normalize_text(value: str) -> str:
    return value.strip().lower()

先頭_は「外部公開を意図しない内部用」という慣習です。アクセスを物理的に禁止するものではありません。

補足:名前マングリング

class Account:
    def __init__(self) -> None:
        self.__token = "sample-token"

先頭に__を付けると、継承時の名前衝突を減らすために名前マングリングが行われます。単なるprivateの代替ではありません。

補足:キーワードとの衝突

class_ = "sample"

Pythonのキーワードと衝突する場合は、末尾に_を付けます。

補足:ダンダー名

__init__
__str__
__len__

__name__のようなダンダー名はPythonが特別な用途に予約しています。独自のダンダー名を新しく作らないようにします。


5. インデント・行の長さ・空行

5-1. インデントはスペース4つ

def calculate_total(price: int, quantity: int) -> int:
    subtotal = price * quantity
    return subtotal
  • タブとスペースを混在させない
  • 継続行は見やすく揃える
total = calculate_total(
    price=200,
    quantity=3,
)

5-2. 行の長さ

PEP 8の基本:

対象 推奨上限
コード 79文字
コメント・ドックストリング 72文字

ただし、BlackやRuff Formatterなど、88文字を標準とするツールもあります。案件設定を優先します。

5-3. トップレベル定義の間は空行2行

DEFAULT_PRICE = 200


def calculate_total(price: int, quantity: int) -> int:
    return price * quantity


class Order:
    pass

5-4. クラス内のメソッド間は空行1行

class Order:
    def __init__(self, total: int) -> None:
        self.total = total

    def is_free_shipping(self) -> bool:
        return self.total >= 3000

5-5. 演算子で改行する場合

読みやすい例:

total_price = (
    item_price
    + shipping_fee
    + handling_fee
    - discount
)

演算子を次の行の先頭に置くと、各項の関係を読み取りやすくなります。


6. importの書き方

6-1. ファイル先頭にまとめる

from __future__ import annotations

import json
from pathlib import Path

import requests

from shop_tools.pricing import calculate_total

6-2. グループを空行で分ける

1. 標準ライブラリ
2. 外部ライブラリ
3. 自作・ローカルパッケージ

6-3. 原則1行1モジュール

# 推奨
import os
import sys

# 避ける
import os, sys

from形式では、同じモジュールから複数名を読み込めます。

from pathlib import Path, PurePath

6-4. ワイルドカードを避ける

# 名前の出所が分かりにくくなる
from sample_module import *

推奨:

from sample_module import calculate_total

6-5. 標準的な別名

import numpy as np
import pandas as pd

プロジェクトやライブラリで広く定着している別名を使います。独自で分かりにくい略称を増やさないようにします。


7. 空白・改行・式の書き方

7-1. 演算子の前後に空白

subtotal = price * quantity
total = subtotal + tax
is_valid = total >= 0

7-2. カンマの後に空白

items = ["apple", "banana", "orange"]

7-3. 括弧の内側に不要な空白を入れない

# 推奨
print(calculate_total(200, 3))

# 避ける
print( calculate_total( 200, 3 ) )

7-4. 添字・スライス

items[0]
items[1:3]

7-5. キーワード引数の=周辺

# キーワード引数では空白を入れない
total = calculate_total(price=200, quantity=3)

型注釈とデフォルト値を併用する場合:

def calculate_tax(subtotal: int, tax_rate: float = 0.10) -> int:
    return int(subtotal * tax_rate)

7-6. 複合文を1行へ詰め込まない

# 避ける
a = 1; b = 2

# 推奨
a = 1
b = 2
# 避ける
if is_valid: process()

# 推奨
if is_valid:
    process()

7-7. 末尾カンマ

複数行のリストや引数では末尾カンマを付けると、差分が見やすくなります。

items = [
    "apple",
    "banana",
    "orange",
]

8. コメントとドックストリング

コメント

「何をしているか」をコードが表し、「なぜそうするか」をコメントで補います。

# 外部APIの仕様上、金額は整数へ切り捨てて送信する。
tax = int(subtotal * tax_rate)

避けたい例:

# subtotalにtaxを足す
total = subtotal + tax

コードと同じ内容を繰り返しているだけです。

インラインコメント

retry_count = 3  # 外部サービスの運用上限
  • 文から十分な空白を取る
  • 多用しない
  • 古くなったコメントを残さない

ドックストリング

def calculate_total(price: int, quantity: int) -> int:
    """単価と数量から合計金額を返す。"""
    return price * quantity

ドックストリングは、モジュール・クラス・関数などの公開仕様を説明します。詳しい規則はPEP 257で扱われます。


9. 推奨される比較・条件式

9-1. Noneisで比較

if result is None:
    print("結果なし")

if result is not None:
    print("結果あり")

避ける:

if result == None:
    pass

9-2. 真偽値を冗長に比較しない

# 推奨
if is_active:
    print("有効")

# 避ける
if is_active == True:
    print("有効")

9-3. 空のコレクションは真偽値で判定

items: list[str] = []

if not items:
    print("商品なし")

9-4. 型判定はisinstance()

if isinstance(value, int):
    print("整数")

避けることが多い例:

if type(value) is int:
    pass

isinstance()は継承関係も考慮します。

9-5. 例外を広く捕まえすぎない

try:
    number = int("100")
except ValueError as error:
    print(f"変換失敗: {error}")

避ける:

try:
    number = int("100")
except Exception:
    pass

10. 実行できる良い例

pep8_sample.py

from __future__ import annotations

from dataclasses import dataclass

TAX_RATE = 0.10
FREE_SHIPPING_THRESHOLD = 3_000


@dataclass(frozen=True)
class OrderItem:
    """注文商品を表す。"""

    name: str
    unit_price: int
    quantity: int

    def subtotal(self) -> int:
        """商品の小計を返す。"""
        return self.unit_price * self.quantity


def calculate_order_total(items: list[OrderItem]) -> tuple[int, int, int]:
    """注文商品の小計・税額・合計を返す。"""
    subtotal = sum(item.subtotal() for item in items)
    tax = int(subtotal * TAX_RATE)
    total = subtotal + tax
    return subtotal, tax, total


def main() -> None:
    """サンプル注文の計算結果を表示する。"""
    items = [
        OrderItem(name="Sample A", unit_price=200, quantity=2),
        OrderItem(name="Sample B", unit_price=200, quantity=1),
    ]

    subtotal, tax, total = calculate_order_total(items)
    shipping_label = (
        "送料無料"
        if total >= FREE_SHIPPING_THRESHOLD
        else "送料別"
    )

    print(f"小計: {subtotal}")
    print(f"税額: {tax}")
    print(f"合計: {total}")
    print(f"配送: {shipping_label}")


if __name__ == "__main__":
    main()

実行:

python pep8_sample.py

実行結果:

小計: 600
税額: 60
合計: 660
配送: 送料別

この例で確認できる規則:

  • モジュール名:pep8_sample.py
  • クラス名:OrderItem
  • 関数・メソッド名:calculate_order_totalsubtotal
  • 変数名:shipping_label
  • 定数名:TAX_RATE
  • インデント:スペース4つ
  • トップレベル定義間:空行2行
  • 複数行要素:末尾カンマ
  • main()による実行入口の分離

11. よくある修正例

命名

# 修正前
def CalculateTotal(ItemPrice, ItemCount):
    return ItemPrice * ItemCount


# 修正後
def calculate_total(item_price: int, item_count: int) -> int:
    return item_price * item_count

長い行

# 修正前
message = create_message(user_name, order_number, ordered_at, payment_method, shipping_address)

# 修正後
message = create_message(
    user_name,
    order_number,
    ordered_at,
    payment_method,
    shipping_address,
)

空白

# 修正前
total=price*quantity+tax

# 修正後
total = price * quantity + tax

複雑な条件

# 修正前
if user is not None and user.is_active and user.age >= 18 and not user.is_blocked:
    process_user(user)

# 修正後
is_available_user = (
    user is not None
    and user.is_active
    and user.age >= 18
    and not user.is_blocked
)

if is_available_user:
    process_user(user)

マジックナンバー

# 修正前
if retry_count >= 3:
    stop_processing()

# 修正後
MAX_RETRY_COUNT = 3

if retry_count >= MAX_RETRY_COUNT:
    stop_processing()

12. 自動チェック・自動整形

RuffでLint

python -m pip install ruff
ruff check .

自動修正可能な項目を修正:

ruff check . --fix

Ruff Formatterで整形

ruff format .

設定例

pyproject.toml

[tool.ruff]
line-length = 88
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "I", "N", "UP"]
ルール群 主な内容
E pycodestyleのエラー系
F Pyflakes系の誤り
I import並び替え
N 命名規則
UP 新しいPython構文への更新提案

自動整形ツールの設定がPEP 8の79文字と異なる場合があります。プロジェクト設定を正として、全員で揃えます。


13. まとめ

全体まとめ

PEP 8はPythonの代表的なコーディングスタイルガイドです。基本的には、モジュール・関数・変数をsnake_case、クラスをCapWords、定数をUPPER_SNAKE_CASEで書きます。インデントはスペース4つ、コードの行長は原則79文字、トップレベルの関数やクラス間は空行2行です。また、importは標準・外部・自作の順で分け、Noneisで比較します。実務ではPEP 8を基準にしつつ、チームと既存プロジェクトの規約を優先します。

命名の最小セット

module_name.py       モジュール
package_name         パッケージ
ClassName            クラス
CustomError          例外
function_name        関数・メソッド
variable_name        変数・引数
CONSTANT_NAME        定数
_internal_name       内部用

最低限の確認

ruff check .
ruff format --check .

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?