[入門] Pythonで学ぶ、より良いコードを書くための実践的テクニック 第1回 プロフェッショナルな可読性への道 (理解しやすいコード/名前付けの極意/コードの美学)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3521573/04129e9b-0ff0-4dcc-b653-ec5026ef385e.png)

https://x.com/ShigemoriMasato

ソフトウェア開発において、コードの可読性[^1]は品質と保守性を左右する最も重要な要素の一つです。本記事シリーズでは、Pythonを題材として、読みやすく理解しやすいコードを書くための実践的なテクニック[^2]を体系的に解説していきます。

全3回にわたって、コードの可読性を向上させる具体的な方法を、豊富な実例とともに紹介します。第1回では、コードの可読性の基本概念から、適切な命名規則[^3]、そしてコードの見た目の美しさまでを扱います。

```mermaid
graph TB
    A[Pythonで学ぶ実践的テクニック]
    B[第1回: 基礎編]
    C[第2回: 制御フロー編]
    D[第3回: 再構成編]
    
    A --> B
    A --> C
    A --> D
    
    B --> E[理解しやすいコード]
    B --> F[名前に情報を詰め込む]
    B --> G[誤解されない名前]
    B --> H[美しさ]
    B --> I[コメントすべきこと]
    
    style B fill:#01abef,stroke:#333,stroke-width:4px
```

## 理解しやすいコード

### 優れたコードの定義

「優れた」コードとは何でしょうか。パフォーマンス[^4]が良いコード？ 短いコード？ いいえ、最も重要なのは**読みやすさ**です。

```python
# === 悪い例：短いが意味不明 ===
def p(l): 
    return [x*2 for x in l if x>0]

# === 良い例：長いが意図が明確 ===
def process_positive_numbers(numbers):
    """正の数を2倍にして返す"""
    doubled_positive_numbers = []
    for number in numbers:
        if number > 0:
            doubled_positive_numbers.append(number * 2)
    return doubled_positive_numbers
```

### 読みやすさの基本定理

> コードは他の人が最短時間で理解できるように記述する必要がある

ここでいう「他の人」には、6ヶ月後の自分自身も含まれます。理解とは、コードを読んで変更・追加・バグ修正[^5]ができるレベルを指します。

```mermaid
graph LR
    A[コードを書く] --> B[他の人が読む]
    B --> C{理解できるか？}
    C -->|Yes| D[変更・追加・修正が可能]
    C -->|No| E[時間の浪費]
    E --> F[技術的負債の蓄積]
    
    style D fill:#9f9,stroke:#333,stroke-width:2px
    style F fill:#f99,stroke:#333,stroke-width:2px
```

### 小さなことは絶対にいいこと？

コード量を減らすことが常に正解とは限りません。理解のしやすさを犠牲にしてまで短くする必要はありません。

```python
# === 悪い例：過度に短縮したコード（論理演算子の悪用） ===
x = a > b and a - b or b - a

# === 良い例：明確な条件分岐 ===
if a > b:
    absolute_difference = a - b
else:
    absolute_difference = b - a
```

## 名前に情報を詰め込む

### 明確な単語を選ぶ

変数名や関数名には、できるだけ具体的で情報量の多い単語を使用します。汎用的な動詞（get、set、check など）[^6]は避け、より具体的な動詞を選びましょう。

```python
# === 悪い例：抽象的で情報量が少ない ===
def get():
    return database.query("SELECT * FROM users")

# === 良い例：具体的で情報量が多い ===
def fetch_all_users_from_database():
    return database.query("SELECT * FROM users")
```

よく使われる動詞の選択肢：

| 汎用的な動詞 | より具体的な選択肢 |
|------------|---------------|
| get | fetch, retrieve, load, download |
| set | save, store, commit, configure |
| check | validate, verify, contains, exists |
| change | update, modify, revise, transform |

### 汎用的な名前を避ける

tmp、retval、result などの汎用的な名前は情報量が少なく、コードの理解を妨げます[^7]。

```python
# === 悪い例：意味を持たない汎用的な名前 ===
def calculate_discount(price, rate):
    tmp = price * rate
    retval = price - tmp
    return retval

# === 良い例：変数の目的が明確な名前 ===
def calculate_discount(price, rate):
    discount_amount = price * rate
    final_price = price - discount_amount
    return final_price
```

### 名前に情報を追加する

変数名に単位や重要な属性を含めることで、誤用を防げます。

```python
# === 悪い例：単位や制約が不明 ===
delay = 10
size = 1024

# === 良い例：単位や制約を名前に含める ===
delay_seconds = 10
max_file_size_mb = 1024
```

```mermaid
graph TD
    A[名前付けのベストプラクティス]
    B[明確な単語を選ぶ]
    C[汎用的な名前を避ける]
    D[追加情報を含める]
    E[スコープに応じた長さ]
    
    A --> B
    A --> C
    A --> D
    A --> E
    
    B --> B1[fetch_user_data]
    C --> C1[discount_amountではなくtmp]
    D --> D1[timeout_seconds]
    E --> E1[i for ループ内<br>user_authentication_status for グローバル]
```

## 誤解されない名前

### 対になる言葉の使い方

プログラミングでは、対になる概念を表す単語のペアが多数存在します[^8]。これらを正しく使い分けることで、コードの意図が明確になります。

| 概念 | 対になる言葉 | 使用例 |
|-----|------------|-------|
| 追加/削除 | add / remove | リストへの要素操作 |
| 開始/停止 | start / stop | プロセスやサービスの制御 |
| 作成/破棄 | create / destroy | オブジェクトのライフサイクル[^9] |
| 接続/切断 | connect / disconnect | ネットワークやDB接続 |
| 取得/設定 | get / set | プロパティアクセス |

### 限界値を含める場合の命名

数値の範囲を表す場合、その境界が含まれるかどうかを明確にする必要があります。

```python
# === 悪い例：上限か下限か不明確 ===
if shopping_cart_size >= CART_LIMIT:
    print("カートがいっぱいです")

# === 良い例：明確に上限値を示す ===
if shopping_cart_size >= MAX_ITEMS_IN_CART:
    print("カートがいっぱいです")
```

### ブール値の命名規則

ブール値[^10]を表す変数には、`is_`、`has_`、`can_` などの接頭辞を付けることで、その変数が真偽値であることを明示します。

```python
# === 悪い例：ブール値かどうか不明 ===
authenticated = True
read = False

# === 良い例：ブール値であることが明確 ===
is_authenticated = True  
has_read_permission = False
can_edit_document = True
```

## 美しさ

### なぜ美しさが大切なのか

コードの見た目の美しさは、単なる美学の問題ではありません。整然としたコードは読みやすく、バグも見つけやすくなります[^11]。

```python
# === 読みにくい例 ===
class StatsKeeper:
  def __init__(self):
    self.count=0
    self.minimum=0
    self.maximum=0
  def Add(self,d):
    ...
  def Average(self):
    ...

# === 読みやすい例 ===
class StatsKeeper:

    def __init__(self):
        self.count = 0
        self.minimum = 0
        self.maximum = 0

    def add(self, data):
        """データを追加する"""
        ...

    def average(self):
        """平均値を計算して返す"""
        ...
```

### 一貫性のある配置

同じような処理は同じような見た目にすることで、パターンが認識しやすくなります。

```python
# === 悪い例：一貫性のない改行 ===
user1 = User("Alice", 25, "alice@example.com")
user2 = User("Bob", 30,
    "bob@example.com")
user3 = User("Charlie",
    35, "charlie@example.com")

# === 良い例：一貫した改行 ===
user1 = User("Alice", 25, "alice@example.com")
user2 = User("Bob", 30, "bob@example.com")  
user3 = User("Charlie", 35, "charlie@example.com")
```

### コードを「段落」に分割する

空行を使ってコードを論理的なブロックに分けることで、全体の構造が把握しやすくなります[^12]。

```python
def process_user_data(user_id):
    # ユーザー情報の取得
    user = get_user(user_id)
    if not user:
        return None
    
    # 関連データを取得
    profile = get_profile(user_id)
    preferences = get_preferences(user_id)
    recent_activities = get_recent_activities(user_id)
    
    # 結果をまとめて返す
    result = {
        "user": user,
        "profile": profile,
        "preferences": preferences,
        "activities": recent_activities
    }
    return result
```

## コメントすべきことを知る

### コメントするべきでは「ない」こと

コードから明らかなことをコメントで繰り返すのは冗長です[^13]。

```python
# === 悪い例：コードから明らかなことをコメント ===
# iに1を加える
i += 1

# userという変数にget_user()の結果を代入
user = get_user()

# === 良い例：なぜそうするのかを説明 ===
# ユーザーのログイン試行回数を増やす
login_attempts += 1

# キャッシュを確認してからDBアクセス  
user = get_user()  # 内部でキャッシュを利用
```

### 自分の考えを記録する

コードの「なぜ」を説明することが重要です。実装の選択理由や、既知の問題をTODOコメント[^14]として残しましょう。

```python
def quick_sort(arr):
    """
    クイックソートアルゴリズムを実装
    
    選択理由：
    - 平均的にO(n log n)の時間計算量
    - インプレースソートで追加メモリが不要
    
    注意事項：
    - 最悪の場合はO(n²)になる
    - TODO: 大規模データセットではヒープソートへの切り替えを検討
    """
    pass
```

```mermaid
graph LR
    A[コメントの種類]
    B[説明すべきこと]
    C[説明すべきでないこと]
    
    A --> B
    A --> C
    
    B --> B1[なぜその実装を選んだか]
    B --> B2[複雑なアルゴリズムの概要]
    B --> B3[既知の問題や制限事項]
    B --> B4[将来の改善点 TODO]
    
    C --> C1[コードから明らかなこと]
    C --> C2[変数名で表現できること]
    C --> C3[悪い設計の言い訳]
    
    style B fill:#9f9,stroke:#333,stroke-width:2px
    style C fill:#f99,stroke:#333,stroke-width:2px
```

## まとめ

第1回では、Pythonを通じて学ぶリーダブルコードの基礎となる5つの重要な概念を解説しました：

1. **理解しやすいコード** - 読みやすさを最優先に考える
2. **名前に情報を詰め込む** - 変数名・関数名から意図が伝わるようにする
3. **誤解されない名前** - 曖昧さを排除し、明確な名前を付ける
4. **美しさ** - 一貫性のある整然としたコードレイアウト
5. **コメントすべきことを知る** - 「なぜ」を説明し、明らかなことは書かない

これらの原則を実践することで、あなたのPythonコードは格段に読みやすくなり、チーム全体の生産性向上につながります。

https://qiita.com/ShigemoriMasato/items/6b7ef6de76ff08cb3b6d

## 参考文献
* Dustin Boswell、Trevor Foucher著、角征典訳『リーダブルコード より良いコードを書くためのシンプルで実践的なテクニック』オライリー・ジャパン、2012年
* Robert C. Martin著、花井志生訳『Clean Code アジャイルソフトウェア達人の技』アスキー・メディアワークス、2009年
* Steve McConnell著、日向俊二訳『Code Complete 第2版 完全なプログラミングを目指して』日経BP社、2005年

[^1]: **可読性** - コードがどれだけ読みやすく、理解しやすいかを表す指標。保守性や拡張性に直結する重要な品質特性。
[^2]: **実践的なテクニック** - 理論だけでなく、実際の開発現場で即座に適用できる具体的な手法やパターン。
[^3]: **命名規則** - 変数、関数、クラスなどの名前付けに関する一貫したルール。camelCase、snake_case、PascalCaseなどがある。
[^4]: **パフォーマンス** - プログラムの実行速度やメモリ使用効率などの性能指標。
[^5]: **バグ修正** - プログラムの不具合（bug）を特定し、正しい動作をするように修正すること。デバッグ（debugging）とも呼ばれる。
[^6]: **汎用的な動詞** - get、set、checkなど、多くの文脈で使用される抽象度の高い動詞。具体性に欠けるため、コードの意図が不明確になりやすい。
[^7]: **コードの理解を妨げる** - 変数の役割や目的が不明確になり、コードを読む人が推測や調査に時間を費やすことになる状態。
[^8]: **対になる概念** - プログラミングにおいて頻繁に登場する反対の意味を持つ操作のペア。一貫性を保つことで可読性が向上する。
[^9]: **ライフサイクル** - オブジェクトが生成されてから破棄されるまでの一連の過程。create→use→destroyという流れ。
[^10]: **ブール値** - true（真）またはfalse（偽）の2つの値のみを取るデータ型。条件判定に使用される。
[^11]: **バグを見つけやすくなる** - コードが整理されていると、異常なパターンや不整合が視覚的に目立つため、問題の早期発見につながる。
[^12]: **論理的なブロック** - 関連する処理をまとめたコードの単位。段落分けすることで、各ブロックの役割が明確になる。
[^13]: **冗長** - 必要以上に長く、くどいこと。コメントの場合、情報価値のない繰り返しを指す。
[^14]: **TODOコメント** - 将来的に実装や改善が必要な箇所を示すコメント。`TODO:` で始めるのが一般的な慣習。