【Python】良いコメントは「何を」ではなく「なぜ」を書く:コードで語らせる設計術

「コードにはコメントを書きましょう」というのは、プログラミングを学ぶ上で誰もが受けるアドバイスです。しかし、どのようなコメントが本当に「良いコメント」なのでしょうか?ただ闇雲にコードの説明を書き連ねるだけでは、かえってコードを読みにくくしてしまうことさえあります。

優れたコードとは、それ自体がドキュメントのように振る舞う「自己文書化されたコード」です。そして、それを補う優れたコメントとは、コードが**「何を」しているかを説明するのではなく、「なぜ」**そのように書かれているのか、その背景にある意図や設計判断を伝えるものです。

目次

問題点:「何を」を説明する冗長なコメント

まず、あまり価値のないコメントの例を見てみましょう。ショッピングカート内の商品の合計金額を計算するコードです。

# 悪い例:コードを読めばわかる「何」を説明している
def calculate_total_price(cart_items: list) -> float:
    
    # 合計金額を0で初期化
    total = 0.0
    
    # カート内の商品を一つずつループ
    for item in cart_items:
        # 商品の価格と数量を掛けて、合計に加算
        total += item.price * item.quantity
        
    # 合計を返す
    return total

これらのコメントは、コードをそのまま日本語に翻訳しているだけで、新しい情報を何も提供していません。total = 0.0 を見れば「合計を初期化している」ことは一目瞭然です。このようなコメントは、コードの変更に追従できずに古くなると、むしろ誤解を招くノイズになってしまいます。


解決策①:「なぜ」を語るコメントを書く

良いコメントは、コードだけでは読み取れない背景情報設計上の判断を補足します。

例えば、複数のユーザー情報を一括で更新する処理を考えます。パフォーマンスを考慮して、特定の書き方を選択した場合、その理由をコメントで残すことは非常に有益です。

# 良い例:なぜこの実装にしたのか、という「理由」を説明している
def deactivate_users(users: list[User]):
    """
    指定された複数のユーザーを非アクティブ化する。
    
    # パフォーマンス上の理由から、ここではループ内で個別にsave()を呼び出さない。
    # ORMのbulk_updateを使うことで、DBへのUPDATEクエリを一度にまとめ、
    # N+1問題を回避している。
    """
    for user in users:
        user.is_active = False
        
    User.objects.bulk_update(users, ["is_active"])

このコメントは、bulk_update という手法を選んだ**「なぜ」**(パフォーマンス、N+1問題の回避)を明確に伝えています。これにより、将来このコードを読む開発者は、この実装の重要性を理解し、誤って非効率な形に書き換えてしまうことを防げます。

「なぜ」コメントが有効なケース:

  • パフォーマンス上の最適化: なぜこのアルゴリズムや手法を選んだのか。
  • 設計上のトレードオフ: あるライブラリのバグを回避するための、一見不自然に見えるコードなど。
  • ビジネスロジックの背景: なぜ消費税の計算がこのタイミングで行われるのか、といった業務要件に関する注釈。

解決策②:コメントを不要にする「自己文書化コード」

さらに理想的なのは、コメントを書く必要がないほど、コード自体を分かりやすくすることです。複雑な一行のコードを、意図が明確な名前を持つ関数に切り出すのは、その最も効果的な手法の一つです。

例えば、商品コードが特定のフォーマットに合致するかを正規表現でチェックするコードを考えてみましょう。

あまり良くない例(コメントが必要):

# 商品コードが "P" + 10桁の数字であるかチェック
if re.match(r"^P[0-9]{10}$", product_code):
    # ... 処理 ...

このコメントは、複雑な正規表現の意味を説明するために必要になっています。

より良い例(関数化して自己文書化する): このロジックを、名前で意図を語る関数に切り出します。

def is_valid_product_code_format(code: str) -> bool:
    """商品コードが正規のフォーマット(例: P1234567890)か検証する。"""
    return bool(re.match(r"^P[0-9]{10}$", code))

# 呼び出し側
if is_valid_product_code_format(product_code):
    # ... 処理 ...

is_valid_product_code_format という関数名自体が、以前のコメントと同じ役割を果たしています。コードを読むだけで「商品コードのフォーマットを検証している」ことが直感的に理解でき、もはや処理内容を説明するコメントは不要です。


まとめ

効果的なコメントの書き方と、コードの記述には、次のような優先順位があります。

  1. 【最良】自己文書化されたコード: まず、変数名や関数名を分かりやすくし、ロジックを単純化することで、コメントがなくても理解できるコードを目指す。
  2. 【次善】「なぜ」を説明するコメント: コードだけでは伝わらない設計意図、背景、トレードオフなどを補足するためにコメントを書く。
  3. 【避けるべき】「何を」を説明するコメント: コードを読めばわかることを冗長に説明するコメントは書かない。

コメントを書く前に、まず「このコードはもっと分かりやすくできないか?」と自問自答してみましょう。そして、どうしてもコードで表現しきれない「なぜ」の部分を、簡潔なコメントで伝えることを心がけてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次