「コードは動いてるんだけど、なんか汚い気がする…」
そんなモヤモヤ、感じたことありませんか? 実は、初心者のうちに書いてしまいがちな「アンチパターン(悪い書き方のパターン)」がいくつかあって、知らないうちにそれをやってしまっている可能性が高いんです。
今回は、初心者がよくハマる 5つのアンチパターン を、Pythonコード例とともにわかりやすく解説します。「むずかしそう」を「できそう」に変えていきましょう! 🚀
🎯 対象読者

Pythonを書き始めて間もない方、または「なんとなく動くけど自信がない」という初〜中級者の方にぴったりの内容です。この記事を読めば、コードレビューで指摘されやすいポイントを事前に把握できますよ。
❌ アンチパターン1:引数が多すぎる関数
関数に引数をどんどん追加していくと、こんなことになりがちです。
# ❌ 悪い例:引数が多すぎて何が何だかわからない
def create_user(name, age, email, country, city, role, is_active):
pass
create_user("田中太郎", 25, "tanaka@example.com", "Japan", "Tokyo", "admin", True)
# → 呼び出し側を見ても、何番目が何の値かわからない!
引数が4つ以上になってきたら危険信号です。呼び出し側のコードを見たとき、True や "admin" が何を意味しているのかパッと分かりません。
✅ 改善策:データクラスや辞書にまとめる
from dataclasses import dataclass
@dataclass
class UserParams:
name: str
age: int
email: str
country: str
city: str
role: str
is_active: bool
def create_user(params: UserParams):
pass
# 呼び出し側が格段に読みやすくなる!
params = UserParams(
name="田中太郎",
age=25,
email="tanaka@example.com",
country="Japan",
city="Tokyo",
role="admin",
is_active=True
)
create_user(params)
dataclass を使えば、引数をひとまとめにしつつ、型ヒントもついて一石二鳥です。
❌ アンチパターン2:意味のない変数名
「とりあえず動かしたい」という気持ちはわかりますが、変数名に a・x・tmp を使いすぎると後で地獄を見ます。
# ❌ 悪い例:変数名が何を意味するか全くわからない
def calc(a, b, c):
x = a * b
y = x - c
return y
result = calc(1200, 8, 500)
print(result) # → 9100 … これは何??
✅ 改善策:変数名で「何を表しているか」を明示する
# ✅ 良い例:変数名を読むだけで処理が想像できる
def calc_monthly_profit(unit_price, quantity, fixed_cost):
sales_amount = unit_price * quantity
monthly_profit = sales_amount - fixed_cost
return monthly_profit
profit = calc_monthly_profit(1200, 8, 500)
print(profit) # → 9100(月次利益)
「3ヶ月後の自分が読んでもわかるか?」を基準に命名しましょう。コメントより先に、変数名で語れるコードが理想です。
❌ アンチパターン3:同じ処理をコピペしまくる(DRY原則違反)
「動いたからコピーして貼ればいいや」という発想は、バグの温床になります。
# ❌ 悪い例:同じような処理が至るところに散らばっている
print("=" * 30)
print("ユーザー情報")
print("=" * 30)
# ... 何十行か後 ...
print("=" * 30)
print("注文情報")
print("=" * 30)
# ... さらに後 ...
print("=" * 30)
print("配送情報")
print("=" * 30)
この状態で「区切り線を = から - に変えたい」となったら、全箇所を探して修正しなければなりません。修正漏れが起きると、それがバグになります。
✅ 改善策:共通処理を関数にまとめる(DRY原則)
# ✅ 良い例:1か所直すだけで全体に反映される
def print_section_header(title, width=30):
print("-" * width)
print(title)
print("-" * width)
print_section_header("ユーザー情報")
print_section_header("注文情報")
print_section_header("配送情報")
DRY原則(Don’t Repeat Yourself)とは「同じことを繰り返すな」という考え方です。同じ処理が2回以上出てきたら、関数化を検討しましょう。
❌ アンチパターン4:何でもグローバル変数に入れる
「どこからでも使えるから便利!」とグローバル変数を多用すると、コードが大きくなるにつれて管理が破綻します。
# ❌ 悪い例:グローバル変数が乱用されている
user_name = ""
user_score = 0
user_level = 1
def login(name):
global user_name
user_name = name
def add_score(points):
global user_score, user_level
user_score += points
if user_score >= 100:
user_level += 1
user_score = 0
login("太郎")
add_score(60)
add_score(50)
print(f"{user_name} / レベル{user_level}")
どの関数がグローバル変数を変更しているか追跡するのが大変になり、バグの原因を特定しづらくなります。
✅ 改善策:クラスや関数の引数・戻り値で状態を管理する
# ✅ 良い例:クラスで状態をひとまとめに管理する
class User:
def __init__(self, name):
self.name = name
self.score = 0
self.level = 1
def add_score(self, points):
self.score += points
if self.score >= 100:
self.level += 1
self.score = 0
def status(self):
return f"{self.name} / レベル{self.level} / スコア{self.score}"
user = User("太郎")
user.add_score(60)
user.add_score(50)
print(user.status()) # 太郎 / レベル2 / スコア10
クラスを使うことで、状態の変更が user オブジェクトの中に閉じ込められ、追跡しやすくなります。
❌ アンチパターン5:例外をそのまま握りつぶす
エラーが出たとき、「とりあえず try-except で囲めばいいか」と例外を何も処理せずに握りつぶすのはとても危険です。
# ❌ 悪い例:例外を丸ごと無視している
def get_user_age(data, key):
try:
return data[key]
except:
pass # 何も起きなかったように続行…
user_data = {"name": "花子", "age": 22}
age = get_user_age(user_data, "agee") # キーのタイポ!
print(f"年齢:{age}") # → 年齢:None(気づかないまま進んでしまう)
この書き方だと、エラーが起きても何も起きなかったように見えるため、バグの発見が大幅に遅れます。
✅ 改善策:例外の種類を特定し、適切に処理する
# ✅ 良い例:例外の種類を指定し、ログを残す or デフォルト値を返す
def get_user_age(data, key):
try:
return data[key]
except KeyError:
print(f"[警告] キー '{key}' が見つかりません。Noneを返します。")
return None
except TypeError:
print("[エラー] dataが辞書ではありません。")
raise
user_data = {"name": "花子", "age": 22}
age = get_user_age(user_data, "agee")
# → [警告] キー 'agee' が見つかりません。Noneを返します。
ポイントは3つです。
- 例外の種類を絞る(
except:やexcept Exception:で全部捕まえるのは避ける) - 何が起きたかをログに残す(
printでも最低限OK) - どうしようもないエラーは
raiseで再送出する
📋 まとめ:5つのアンチパターン一覧
| # | アンチパターン | 改善の方向性 |
|---|---|---|
| 1 | 引数が多すぎる関数 | dataclassや辞書でまとめる |
| 2 | 意味のない変数名 | 読めば意味がわかる名前にする |
| 3 | コピペの乱用(DRY違反) | 共通処理を関数にまとめる |
| 4 | グローバル変数の多用 | クラスや関数スコープで管理する |
| 5 | 例外の握りつぶし | 種類を特定して適切に処理する |
どれも「動くから問題ない」と思いがちですが、コードは書いた後に読まれるものです。特にチーム開発や、数ヶ月後の自分が読み返すときに、このアンチパターンが積み重なっているとかなり苦労します。
🎉 おわりに
今回紹介した5つのアンチパターンは、どれも「知っているかどうか」だけの差です。完璧なコードを最初から書く必要はありません。まずは「あ、これやってたかも」と気づくことが第一歩です。
ぜひ自分の過去のコードを見返して、一つでも改善してみてください。それだけで、あなたのコードの質はぐっと上がりますよ 💪





