📝

Pythonの命名規則とルール

2024/07/22に公開

1.  記事の目的

PEP8 に基づいて Python の命名規則やルールについてまとめる

1.1. インデント

Python ではインデントを使ってコードブロックを示す。
PEP8 では、インデントにスペース 4 つを使うことを推奨。

def my_function():
    print("Hello, world!")

1.2. 行の長さ

1 行の長さは 79 文字以内に抑える。
コードの可読性を保つため。長くなる場合は、適切な位置で改行を入れる。

# 例: 長い行の改行
my_long_variable_name = (
    "これは非常に長い文字列で、79文字を超えるため適切な位置で改行しています。"
)

1.3. 空白の使い方

演算子の前後にはスペースを入れるが、関数や引数の括弧の内側にはスペースを入れない。

# 正しい例
x = 5 + 3
y = (x + 2) * 3

# 関数呼び出しの例
my_function(arg1, arg2)

# 関数定義の例
def my_function(param1, param2):
    pass

1.4. コメント

コメントはコードの意図や説明を明確にするために使う。
コメントは、コードの上に置くか、行の終わりに追加する。

# これはコメントです
x = 10  # これは変数xに10を代入しています

1.5. 変数名と関数名

変数名と関数名は小文字で書き、単語の区切りにはアンダースコアを使う(スネークケース)。

# 変数名の例
user_name = "John Doe"

# 関数名の例
def calculate_sum(a, b):
    return a + b

1.6. クラス名

クラス名は単語の最初の文字を大文字にする(キャメルケース)。

class MyClass:
    def __init__(self, value):
        self.value = value

1.7. 定数

定数はすべて大文字で書き、単語の区切りにはアンダースコアを使う。

PI = 3.14159
MAX_USERS = 100

1.8. インポート

インポート文はファイルの先頭にまとめて書き、標準ライブラリ、サードパーティライブラリ、自分のモジュールの順に並べる。

# 標準ライブラリ
import os
import sys

# サードパーティライブラリ
import numpy as np

# 自分のモジュール
import my_module

1.9. ドキュメンテーション文字列(Docstrings)

関数やクラス、モジュールにはドキュメンテーションストリングを使って説明を追加する。

def my_function(param1, param2):
    """
    この関数はparam1とparam2を加算して返します。

    :param param1: 加算する最初の数値
    :param param2: 加算する2番目の数値
    :return: 加算結果
    """
    return param1 + param2

続きとして、さらに詳しい PEP 8 のルールについて説明します。

1.10. 複合文(Compound Statements)

複数の文を同じ行に書くことは避けるべき。
特に、条件文やループ文では、それぞれの文を新しい行に書くようにする。

# 避けるべき例
if x == 1: print("x is 1")

# 推奨される例
if x == 1:
    print("x is 1")

1.11. 複数のインポートを同じ行に書かない

複数のモジュールをインポートする際は、それぞれのモジュールを個別の行に書く。

# 避けるべき例
import os, sys

# 推奨される例
import os
import sys

1.12. エンプティ行(空行)

コードを読みやすくするために、適切な場所に空行を挿入する。
特に、クラスの定義や関数の定義の間には空行を入れることが推奨される。

  • トップレベルの関数とクラスの定義の間には 2 つの空行を入れる。
  • クラスの中のメソッド定義の間には 1 つの空行を入れる。
# トップレベルの関数の例
def function_one():
    pass


def function_two():
    pass


class MyClass:
    def method_one(self):
        pass

    def method_two(self):
        pass

1.13. テキストのデコレータ

デコレータは関数やメソッドの直前の行に書く。
デコレータが複数ある場合は、それぞれを別々の行に書く。

# 単一のデコレータ
@staticmethod
def my_static_method():
    pass

# 複数のデコレータ
@classmethod
@staticmethod
def my_class_method():
    pass

1.14. 一貫した戻り値の使用

関数やメソッドが何も返さない場合、明示的にreturn Noneを使用するのが一般的。
コードの一貫性を保つため。

def my_function(value):
    if value:
        return value
    return None

1.15. アノテーション

関数アノテーションは、関数の引数や戻り値の型を明示するために使う。
コードの理解を助け、エラーを防ぐ手段として有効。

def greet(name: str) -> str:
    return f"Hello, {name}"

1.16. 例外処理

例外をキャッチする際には、特定の例外をキャッチするようにする。
また、必要以上に広範な例外をキャッチすることは避ける。

# 推奨される例
try:
    result = 1 / 0
except ZeroDivisionError:
    print("Cannot divide by zero")

# 避けるべき例
try:
    result = 1 / 0
except Exception:
    print("An error occurred")

1.17. パッケージとモジュールの命名

パッケージ名は短くてすべて小文字にし、アンダースコアは避ける。
モジュール名もすべて小文字にし、必要ならアンダースコアを使うこと。

# パッケージ名の例
import mypackage

# モジュール名の例
import my_module

1.18. 文字列の引用符

文字列を表現する際、シングルクォート(')かダブルクォート(")のどちらかを一貫して使用する。
ただし、文字列内に引用符を含む場合は、それに応じて適切な引用符を選ぶ。

# シングルクォートの例
greeting = 'Hello, world'

# ダブルクォートの例
quote = "She said, 'Hello!'"

1.19. ファイルのエンコーディング

ソースファイルのエンコーディングが UTF-8 であることを示すために、ファイルの先頭にエンコーディングの宣言を追加します。特に、非 ASCII 文字を含む場合に重要。

# -*- coding: utf-8 -*-

1.20. 可変長引数とキーワード引数

関数が可変長引数やキーワード引数を取る場合、それらの引数の前にスペースを入れない。

def my_function(*args, **kwargs):
    pass

1.21. リストの内包表記

リストの内包表記は短く、明確に保つことができる。
複雑になりすぎる場合は、通常の for ループを使用することを検討する。

# リストの内包表記の例
squares = [x**2 for x in range(10)]

# 通常のforループの例
squares = []
for x in range(10):
    squares.append(x**2)

1.22. 名前付き引数のデフォルト値

名前付き引数のデフォルト値として可変オブジェクト(リストや辞書など)を使用しない。
代わりに、Noneを使用し、関数内でその値を設定する。

# 避けるべき例
def my_function(a, b=[]):
    pass

# 推奨される例
def my_function(a, b=None):
    if b is None:
        b = []

1.23. プライベートなメンバー

クラスのプライベートなメンバーには、先頭にアンダースコアを 2 つ付けることで名前をマングリングし、外部からのアクセスを防ぐ。

class MyClass:
    def __init__(self):
        self.__private_member = 42

1.24. コンテキストマネージャ

リソースを扱う際には、コンテキストマネージャを使用してリソースを確実に解放する。
with文を使うと、ファイルやデータベース接続などのリソースを安全に扱える。

# ファイル操作の例
with open('file.txt', 'r') as file:
    content = file.read()

1.25. 型ヒント(Type Hinting)

Python 3.5 以降では、型ヒントを使用して関数の引数や戻り値の型を明示することができる。
これはコードの理解と保守を助ける。

def greeting(name: str) -> str:
    return f"Hello, {name}"

1.26. 可読性を保つための関数の短さ

関数は短く、1 つの明確な目的を持つようにする。
長く複雑な関数は、複数の小さな関数に分割して、可読性と再利用性を高める。

# 長い関数を分割する例
def process_data(data):
    cleaned_data = clean_data(data)
    analyzed_data = analyze_data(cleaned_data)
    return analyzed_data

def clean_data(data):
    # データをクリーニングする処理
    pass

def analyze_data(data):
    # データを分析する処理
    pass

1.27. デバッグ用のプリント文

デバッグのために使用するプリント文は、コードのリリース前に削除するか、ログを使用するようにする。
loggingモジュールを使用することで、異なるログレベルに応じた出力を行える。

import logging

logging.basicConfig(level=logging.INFO)
logging.info('This is an informational message')

1.28. モジュールとスクリプトの区別

モジュールとしてもスクリプトとしても使用できるコードには、以下の構造を持たせる。
これにより、直接実行時とインポート時の動作を区別できる。

def main():
    # メインの処理
    pass

if __name__ == "__main__":
    main()

1.29. クラスのドキュメント

クラスにはクラスレベルのドキュメンテーションストリングを追加し、そのクラスの目的と使用方法を説明する。
必要に応じて、個々のメソッドにもドキュメンテーションストリングを追加する。

class MyClass:
    """
    このクラスはデータの処理を行います。

    属性:
        value (int): 処理するデータの値
    """

    def __init__(self, value: int):
        """
        クラスのコンストラクタ。

        :param value: 初期値
        """
        self.value = value

    def process(self):
        """
        データの処理を行います。

        :return: 処理結果
        """
        return self.value * 2

参考にした記事(いつもありがとうございます)


GitHubで編集を提案

Discussion