[Pythonのはじめ方] Part35: リファクタリングとPEP8

Python

はじめに 🚀

Pythonの学習が進み、自分でプログラムを書けるようになってくると、「もっと良いコードを書きたい!」と思うようになりますよね。そんな時に役立つのが「リファクタリング」と「PEP8」という考え方です。

リファクタリングは、コードの見た目の動きを変えずに、中身をより良く整理整頓すること。PEP8は、Pythonコードの書き方に関する公式なルールブックのようなものです。

これらを学ぶことで、あなたの書くPythonコードは格段に読みやすく、修正しやすくなり、他の人との共同作業もスムーズになります。さあ、一緒に学んでいきましょう!💪

リファクタリングとは? 🛠️

リファクタリングとは、プログラムの外部から見たときの動作を変えずに、内部の構造を改善していくことです。例えるなら、部屋の模様替えはせずに、散らかったものを片付けたり、収納を見直したりするイメージです。

リファクタリングの目的

  • 可読性の向上: コードが読みやすくなり、理解しやすくなります。
  • 保守性の向上: 機能追加や修正がしやすくなります。
  • バグの発見・修正しやすさ向上: コードが整理されることで、隠れたバグが見つかりやすくなったり、修正が容易になったりします。
  • パフォーマンスの向上: より効率的な処理に書き換えることで、実行速度が向上する場合もあります。

簡単なリファクタリングの例

具体的な例を見てみましょう。

修正前(Before)

# 消費税を計算する関数
def calc(price):
  p = price * 1.1 # 1.1 は消費税率10%
  return p

# 商品Aの税込価格
item_a_price = 1000
item_a_tax_included = calc(item_a_price)
print(item_a_tax_included)

修正後(After)

# 消費税率を定数として定義
TAX_RATE = 1.1

# 消費税込み価格を計算する関数
def calculate_price_with_tax(price: float) -> float:
  """
  商品の価格に消費税を加えた金額を返す

  Args:
      price (float): 税抜価格

  Returns:
      float: 税込価格
  """
  price_with_tax = price * TAX_RATE
  return price_with_tax

# 商品Aの税込価格
item_a_price = 1000.0
item_a_tax_included = calculate_price_with_tax(item_a_price)
print(item_a_tax_included)

改善点 ✨

  • 関数名をより具体的に (calccalculate_price_with_tax)
  • 変数名を分かりやすく (pprice_with_tax)
  • マジックナンバー (1.1) を定数 (TAX_RATE) に変更
  • 型ヒント (: float, -> float) を追加して、関数の使い方を明確化
  • Docstring(関数の説明文)を追加

このように、変数名や関数名を分かりやすくしたり、直接書かれた数値(マジックナンバー)に名前を付けたりするだけでも、コードはずっと読みやすくなります。

PEP 8 とは? 📖

PEP 8 (ペップエイト) は、Pythonコードの公式スタイルガイドです。Pythonの生みの親であるGuido van Rossum氏などが作成しました。コードの見た目や書き方を統一するためのルール集で、世界中のPythonプログラマーに広く読まれ、実践されています。

なぜPEP 8に従うべきか?

  • コードの一貫性: 誰が書いても同じようなスタイルのコードになり、読みやすくなります。
  • チーム開発の円滑化: 複数人で開発する際に、コードのスタイルが統一されているとコミュニケーションがスムーズになります。
  • 読みやすいコードは良いコード: 読みやすいコードは、バグが少なく、メンテナンスしやすい傾向があります。

Pythonはインデント(字下げ)が文法の一部であるなど、元々コードの見た目を重視する言語ですが、PEP 8に従うことでさらにそのメリットを高めることができます。

PEP 8 の主なルール(一部)

PEP 8には多くのルールがありますが、ここでは特に重要なものをいくつか紹介します。

項目 ルール
インデント スペース4つを使用する。タブは使わない。
if x > 0:
    print("Positive") # OK
# if x > 0:
# print("Positive") # NG (インデントがない)
# if x > 0:
#  print("Positive") # NG (スペース2つ)
1行の長さ 最大79文字(半角)に抑える。
# 長い行はバックスラッシュ(\)や括弧()で折り返す
long_variable_name = some_function(param1, param2,
                                   param3, param4)

total = (value1 + value2 + value3 +
         value4 + value5 + value6)
空行 関数やクラス定義の間、メソッド定義の間には適切な数の空行を入れる(通常は関数/クラス間は2行、メソッド間は1行)。
def function1():
    pass


def function2():
    pass

class MyClass:
    def method1(self):
        pass

    def method2(self):
        pass
import文
  • ファイル冒頭にまとめて書く。
  • 標準ライブラリ、サードパーティライブラリ、自作モジュールの順にグループ化し、間を1行空ける。
  • 1行に1つのモジュールをインポートする。
import os
import sys

import requests

from my_module import my_function

# NG例: import os, sys
空白(スペース) 演算子の前後、カンマの後にはスペースを入れる。関数呼び出しの括弧の直前や、キーワード引数の=の前後にスペースは入れない。
x = y + 1 # OK
my_list = [1, 2, 3] # OK
print(x) # OK

# NG例
# x=y+1
# my_list = [1,2,3]
# print (x)
# def func(arg = 1): pass
命名規則
  • 関数、変数: スネークケース (my_function, user_name)
  • クラス: キャメルケース(CapWords) (MyClass, UserModel)
  • 定数: 大文字のスネークケース (MAX_SIZE, PI)
def calculate_area(radius):
    pass

class UserProfile:
    pass

MAX_CONNECTIONS = 10
コメント
  • コードと矛盾しないように書く。
  • ブロックコメント (# から始まる行全体) は # の後にスペースを入れる。
  • インラインコメント (コードと同じ行) はコードと最低2つのスペースで区切り、# の後にスペースを入れる。
# これはブロックコメントです
x = 10  # これはインラインコメントです

これらは一部ですが、基本的なルールを守るだけでもコードの見た目は大きく改善されます。

PEP 8をチェックするツール 🤖

PEP 8のルールをすべて覚えて手動でチェックするのは大変です。幸いなことに、コードがPEP 8に準拠しているかを自動でチェックしたり、修正したりしてくれる便利なツールがあります。

flake8: コードチェッカー

flake8 は、コードがPEP 8に違反していないか、論理的なエラー(使われていない変数など)がないかなどをチェックしてくれるツールです。静的解析ツールとも呼ばれます。

  1. インストール:
    pip install flake8
  2. 使い方:
    flake8 your_python_file.py

    上記コマンドを実行すると、問題のある箇所とエラーコードが表示されます。

    your_python_file.py:3:2: E225 missing whitespace around operator
    your_python_file.py:5:1: F401 'os' imported but unused

    例えば上記は、「3行目の2文字目で演算子の周りに空白がない (E225)」ことと、「5行目の1文字目でosモジュールがインポートされているが使われていない (F401)」ことを示しています。

flake8 はエラーを指摘するだけで、コードを自動修正はしません。

autopep8: 自動フォーマッター

autopep8 は、PEP 8のスタイルガイドに違反している箇所を自動的に修正してくれるツールです。

  1. インストール:
    pip install autopep8
  2. 使い方:
    • 差分表示 (修正内容を確認):
      autopep8 --diff your_python_file.py
    • ファイルを直接修正 (上書き):
      autopep8 --in-place your_python_file.py
    • 修正結果を新しいファイルに出力:
      autopep8 your_python_file.py > new_file.py

autopep8 を使えば、インデントや空白の修正などを自動で行ってくれます。

その他のツール

  • Black: より強力な自動フォーマッター。”妥協しない”コードフォーマッターとして知られ、細かい設定なしに一貫したスタイルを強制します。
  • Ruff: Pythonリンター兼フォーマッター。非常に高速に動作することが特徴で、近年人気が高まっています。flake8autopep8 などの機能を統合しています。

これらのツールを開発環境(VSCodeなどのエディタ)と連携させると、ファイルを保存したときに自動的にチェックやフォーマットを実行するように設定でき、非常に便利です。

リファクタリングとPEP 8の実践 ✍️

では、簡単なコードを例に、PEP 8違反を修正し、リファクタリングを行ってみましょう。

修正前のコード

import math

def Area(r):
 result= r*r*math.pi
 return result

radius = 5
a=Area(radius)

print("半径"+str(radius)+"の円の面積は"+str(a)+"です")

問題点 🤔

  • PEP 8違反: 関数名が大文字始まり (Area)、変数名が短い (r, a)、演算子の前後にスペースがない (r*r*math.pi)、文字列結合が読みにくい。
  • 可読性: 変数名aが何を表しているか分かりにくい。

修正後のコード

import math

# 定数として円周率を定義 (math.piでも良いが、例として)
PI = math.pi

def calculate_circle_area(radius: float) -> float:
    """円の面積を計算する関数"""
    if radius < 0:
        raise ValueError("半径は0以上である必要があります")
    area = radius * radius * PI
    return area

# 半径
circle_radius = 5.0

# 面積を計算
circle_area = calculate_circle_area(circle_radius)

# 結果を出力 (f-stringを使用)
print(f"半径{circle_radius}の円の面積は{circle_area:.2f}です") # 小数点以下2桁まで表示

改善点 🎉

  • PEP 8準拠: 関数名 (calculate_circle_area)、変数名 (radius, area, circle_radius, circle_area) をスネークケースに。演算子の前後にスペースを追加。
  • 可読性向上: 関数名、変数名が具体的になった。f-stringを使って出力が見やすくなった。
  • リファクタリング:
    • 円周率を定数PIとして定義(必須ではないが、例として)。
    • Docstringと型ヒントを追加。
    • 簡単なエラーハンドリング(半径が負の場合)を追加。
    • 出力時に小数点以下の桁数を指定 (:.2f)。

このように、PEP 8に従ってスタイルを整え、さらにリファクタリングを行うことで、コードはより分かりやすく、再利用しやすく、そして信頼性の高いものになります。

まとめ ✨

今回は、コードの品質を高めるための「リファクタリング」とPythonの公式スタイルガイド「PEP 8」について学びました。

  • リファクタリング は、コードの動作を変えずに内部構造を改善し、読みやすさや保守性を高める手法です。
  • PEP 8 は、Pythonコードの書き方を統一するためのルール集で、コードの一貫性と可読性を保つために重要です。
  • flake8autopep8 といったツールを活用することで、効率的にPEP 8に準拠したコードを書くことができます。

最初は少し面倒に感じるかもしれませんが、リファクタリングとPEP 8を意識してコーディングする習慣をつけることで、将来の自分が(そして他の開発者が)助かる、高品質なコードを書けるようになります。ぜひ、日々のコーディングに取り入れてみてくださいね!😊

参考情報 🔗

コメント

タイトルとURLをコピーしました