← ブログ · · ConvertCaseHQ チーム · 9 分で読めます

Python の PEP 8 命名規則:変数と関数は snake_case

PEP 8 は、関数名と変数名を小文字にし、読みやすさに必要なら単語をアンダースコアで区切るよう定めています。これが snake_case です。total_price や send_invoice() がその例です。クラスには CapWords(InvoiceSender)、定数にはアンダースコアでつないだ大文字(MAX_RETRIES)を使い、モジュールには短くすべて小文字の名前を付けます。ここまでで、普段書く Python のほとんどをカバーできます。

PEP 8 の命名のセクションで役に立つ細かい情報は、その先にあります。先頭や末尾のアンダースコアが何を意味するか、略語をどう扱うか、避けるべき 1 文字の名前、ルールを破るのが正しい判断になる場面などです。以下の内容はすべて PEP 8 そのものと照らして確認してあります。「」で囲んだ英語は、PEP 8 の原文です。

PEP 8 の命名規則の早見表

名前を付ける対象PEP 8 のスタイル例
モジュール短くすべて小文字。役に立つならアンダースコアも可billing.py、tax_rules.py
パッケージ短くすべて小文字。アンダースコアは非推奨payments
クラスCapWordsInvoiceSender
例外CapWords。エラーなら末尾に Error を付けるPaymentDeclinedError
関数、メソッドsnake_casesend_invoice()
変数、インスタンス変数snake_casetotal_price
メソッドの最初の引数self。クラスメソッドでは clsdef from_settings(cls, settings)
定数アンダースコアでつないだ大文字。通常はモジュールレベルMAX_RETRIES
型変数短い CapWordsT、AnyStr
非公開の名前先頭にアンダースコア 1 つ_rate_cache

この表のほとんどを、1 つの小さなモジュールにまとめるとこうなります。

# billing.py
MAX_RETRIES = 3
_rate_cache = {}


class PaymentDeclinedError(Exception):
    pass


class InvoiceSender:
    def __init__(self, smtp_host):
        self.smtp_host = smtp_host
        self._attempts = 0

    def send_invoice(self, invoice_id):
        self._attempts += 1
        ...

    @classmethod
    def from_settings(cls, settings):
        return cls(settings["smtp_host"])

あまり使われない 2 つの行も、知っておく価値があります。型変数には、共変性や反変性を示すために _co や _contra の接尾辞を付けられます。VT_co = TypeVar('VT_co', covariant=True) がその例です。また、グローバル変数には関数のルールが適用されます。モジュールを from module import * で使うことを想定している場合、PEP 8 は公開する名前を __all__ に列挙するよう勧めています。

そもそもなぜ snake_case なのか

PEP 8 は 2001 年 7 月に作られ、著者として挙げられているのは Guido van Rossum、Barry Warsaw、Alyssa Coghlan です。出発点は Guido の観察の 1 つで、コードは書かれる回数よりも、読まれる回数のほうがはるかに多い、というものです。命名規則は、この目的のためにあります。アンダースコアがあれば、長い名前(days_since_last_login)でも単語の区切りが見えます。snake_case の値と CapWords のクラスを使い分けていれば、調べる前から、その名前がどんな種類のものかがわかります。PEP 8 は、公開 API についての大原則も定めています。名前は、実装のされ方ではなく、使われ方を反映すべきだ、というものです。

アンダースコアの意味

Python には private キーワードがないため、その役割を慣習としてアンダースコアが担っています。PEP 8 は 4 つの形を認めています。

  • _single_leading:弱い「internal use」(内部用)のサインです。from module import * はこれらの名前を読み込みませんが、ほかに使用を妨げるものはありません。
  • single_trailing_:キーワードとの衝突を避けるためのものです。class_ は clss よりよいとされていますが、PEP 8 は、同義語を使うほうがさらによい場合もあると述べています。
  • __double_leading:クラスの中で使うと、名前修飾(name mangling)が起こります。PEP 8 は、サブクラスの属性との衝突を避ける場合にだけ使うよう提案しており、これを好まない人もいることを認めています。
  • __double_leading_and_trailing__:__init__ や __file__ のような「magic」(魔法の)名前です。PEP 8 は、これを自分で作ってはならず、ドキュメントに載っているものだけを使うよう述べています。

名前修飾は、プライバシーを守る仕組みだと考える人を驚かせます。これは名前の付け替えであって、鍵ではありません。

class Account:
    def __init__(self):
        self.__pin = "1234"

acct = Account()
acct.__pin            # AttributeError
acct._Account__pin    # "1234": the mangled name still works

定数は慣習であって、ルールではない

名前を大文字で書いても、再代入は止められません。Python は MAX_RETRIES = 4 を問題なく実行します。ツールに強制させたいなら、typing.Final で名前に注釈を付けます。

from typing import Final

MAX_RETRIES: Final = 3
MAX_RETRIES = 4  # still runs, but mypy reports:
                 # Cannot assign to final name "MAX_RETRIES"

大文字が登場するもう 1 つの場所は、Enum のメンバーです。Python ドキュメントの enum HOWTO は、UPPER_CASE のメンバー名を強く推奨しています。Enum は定数を表すものであることと、メソッド名との衝突を避けられることが理由です。class Color(Enum) のメンバー RED と GREEN がその例です。

略語、1 文字の名前、そのほかの例外的なケース

クラス名の中の略語

PEP 8 は、CapWords では略語のすべての文字を大文字にするよう述べています。そのため、HttpServerError より HTTPServerError のほうがよいことになります。標準ライブラリも、http.server.HTTPServer や json.JSONDecodeError のように、ところどころでこれに従っています。snake_case では、略語は単純にすべて小文字になります。parse_json や http_status です。

ツールで名前を付け替えるときには、この点が重要です。当サイトの文字ケース変換ツールは、processOrder を process_order に、HTTPServerError を http_server_error に変換します。snake_case としては、まさに正しい結果です。ただし、PascalCase の出力では略語も普通の単語として書かれるので、HTTP server error は HttpServerError になります。PEP 8 に合わせるには、大文字を手作業で直す必要があります。

避けるべき文字

l(小文字の L)、O(大文字のオー)、I(大文字のアイ)を、1 文字の名前に使ってはいけません。フォントによっては、1 や 0 と区別がつかないからです。

mixedCase

camelCase の関数名が認められるのは、後方互換性のために、すでにそれが主流のスタイルになっている場合に限られます。PEP 8 自身が挙げている例は threading モジュールです。

標準ライブラリが自らのルールを破る理由

PEP 8 は、Python のライブラリの命名が「a bit of a mess」(ちょっとした混乱状態)だと認めています。logging.getLogger() や unittest の assertEqual() は mixedCase ですし、datetime.datetime のように小文字のクラスもあります。list や dict のような組み込み型が小文字なのは、意図的です。PEP 8 は組み込み用に別の規約を定めていて、CapWords を使うのは例外名と組み込み定数だけです。

PEP 8 の 2 つのルールが、これらの名前がほぼそのままである理由を説明しています。1 つ目は、既存のライブラリが別のスタイルを使っている場合は、内部の一貫性を優先する、というものです。2 つ目は、「A Foolish Consistency is the Hobgoblin of Little Minds」(愚かな一貫性は、心の狭い人がおびえる妖怪のようなもの)という見出しのセクションです。PEP 8 との一貫性は大事ですが、プロジェクト内での一貫性はそれ以上に大事で、モジュールや関数の中での一貫性が最も大事だ、という内容です。準拠するためだけに後方互換性を壊してはいけません。unittest のテストクラスが今も setUp() を定義しているのは、そのためです。フレームワークが、まさにその名前を呼び出すからです。

Ruff や pep8-naming で名前を自動チェックする

名前を目で確認する必要はありません。flake8 のプラグイン pep8-naming がチェックしてくれますし、Ruff も同じチェックを N ルールとして実装しています。次のファイルがあるとします。

maxRetries = 3


class order_processor:
    def processOrder(self, orderId):
        totalPrice = 0
        return totalPrice


class InvalidOrder(Exception):
    pass

Ruff は、このファイルのすべての名前を指摘します。

$ ruff check --select N --output-format concise orders.py
orders.py:1:1: N816 Variable `maxRetries` in global scope should not be mixedCase
orders.py:4:7: N801 Class name `order_processor` should use CapWords convention
orders.py:5:9: N802 Function name `processOrder` should be lowercase
orders.py:5:28: N803 Argument name `orderId` should be lowercase
orders.py:6:9: N806 Variable `totalPrice` in function should be lowercase
orders.py:10:7: N818 Exception name `InvalidOrder` should be named with an Error suffix
Found 6 errors.

プロジェクト全体でこのルールを有効にするには、pyproject.toml に追加します。

[tool.ruff.lint]
extend-select = ["N"]

貼り付けたファイルの中で 1 つの識別子を付け替えるときは、当サイトの検索と置換ツールが何件置換したかを表示するので、結果を貼り戻す前の簡単な確認に使えます。コードベース全体なら、ほかのファイルの参照も追随するよう、エディターの名前変更リファクタリングを使ってください。

PEP 8 命名規則のチェックリスト

  • 関数、メソッド、変数、引数は snake_case。
  • クラスは CapWords。略語は大文字にし、例外には Error を付ける。
  • モジュールレベルの定数は、アンダースコアでつないだ大文字。チェッカーに強制させたいなら Final も付ける。
  • モジュール名は短い小文字。パッケージ名ではアンダースコアを避ける。
  • 内部用の名前は先頭にアンダースコア 1 つ。アンダースコア 2 つは、サブクラスとの衝突を避ける場合だけ。
  • 既存のライブラリが別のスタイルを使っているときは、そのライブラリに合わせる。

複数の言語を行き来していますか。当サイトの開発者向けチートシートでは、Python のルールを JavaScript、Java、Go、Rust などと並べて比較しています。

© 2026 ConvertCaseHQ. All rights reserved.