1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python入門早見表

1
Posted at

Python チートシート

Python 3 を前提とした、学習・業務・説明用の早見表です。
「何か」「どう使うか」「他の人へどう説明するか」を短く確認できます。


目次

  1. 基本用語とデータ型一覧
  2. 数値型:int・float
  3. 文字列:str
  4. リスト:list
  5. タプル:tuple
  6. 辞書:dict
  7. 集合:set
  8. 日付と時刻:date・datetime
  9. オブジェクト指向
  10. __init____main__ の違い
  11. 継承・オーバーライド・多重継承
  12. コールスタック・スタックトレース
  13. 例外処理
  14. 説明用まとめ

1. 基本用語とデータ型一覧

変数・オブジェクト・型

name = "Cake"
age = 40

print(type(name))              # <class 'str'>
print(isinstance(age, int))    # True
  • 変数:オブジェクトを参照するための名前
  • オブジェクト:値と振る舞いを持つ実体
  • :そのオブジェクトが扱える値や操作の種類

Pythonでは「変数の箱に値が入る」というより、変数名がオブジェクトを参照すると考えると正確です。

主なデータ型

読み方・正式名 特徴 変更可能か
int イント/integer(インテジャー) 10, -3 整数 不可
float フロート/floating point(フローティング・ポイント) 3.14 小数・浮動小数点数 不可
bool ブール/boolean(ブーリアン) True, False 真偽値 不可
str ストリング/string(ストリング) "Python" 文字列 不可
list リスト [1, 2, 3] 順序あり・重複可
tuple タプル (1, 2, 3) 順序あり・重複可 不可
dict ディクト/dictionary(ディクショナリ) {"name": "Cake"} キーと値の組
set セット {1, 2, 3} 重複なしの集合
NoneType ノンタイプ None 値がないことを表す 不可
date デート date(2026, 7, 22) 日付 不可
datetime デートタイム datetime(2026, 7, 22, 10, 30) 日付と時刻 不可
  • ミュータブル(mutable/ミュータブル):作成後に中身を変更できる
  • イミュータブル(immutable/イミュータブル):作成後に中身を変更できない

型変換

int("100")          # 100
float("3.14")       # 3.14
str(100)             # "100"
list("abc")         # ["a", "b", "c"]
tuple([1, 2])        # (1, 2)
set([1, 1, 2])       # {1, 2}

2. 数値型:intfloat

基本演算

10 + 3      # 13   加算
10 - 3      # 7    減算
10 * 3      # 30   乗算
10 / 3      # 3.333...  除算。結果は基本的にfloat
10 // 3     # 3    切り下げ除算
10 % 3      # 1    余り
10 ** 3     # 1000 べき乗

よく使う関数

abs(-10)              # 10
round(3.14159, 2)     # 3.14
min(3, 8, 1)          # 1
max(3, 8, 1)          # 8
sum([10, 20, 30])     # 60

float の注意

0.1 + 0.2             # 0.30000000000000004 になる場合がある

float は2進数で小数を近似して保持するため、誤差が発生します。金額を厳密に扱う場合は、整数の円単位または Decimal(デシマル)を検討します。

from decimal import Decimal

price = Decimal("0.1") + Decimal("0.2")
print(price)           # 0.3

説明するときの一言
int は整数、float は小数を扱う型です。float には計算誤差があるため、金額などでは注意します。


3. 文字列:str

作成・参照・スライス

text = "Python"

text[0]       # "P"
text[-1]      # "n"
text[1:4]     # "yth"
text[:3]      # "Pyt"
text[3:]      # "hon"
text[::-1]    # "nohtyP"
len(text)     # 6

文字列はイミュータブルなので、特定位置の文字を直接変更できません。

# text[0] = "J"  # TypeError
text = "J" + text[1:]   # "Jython"

よく使う操作

目的 コード 補足
前後の空白を除く text.strip() 左だけは lstrip()、右だけは rstrip()
置換する text.replace("a", "b") 元の文字列は変わらず、新しい文字列を返す
分割する text.split(",") 戻り値はリスト
結合する ",".join(words) 文字列のリストを結合
含まれるか調べる "Py" in text True / False
位置を探す text.find("th") なければ -1
位置を探す text.index("th") なければ ValueError
個数を数える text.count("a") 一致数を返す
大文字にする text.upper() 例:PYTHON
小文字にする text.lower() 例:python
先頭だけ大文字 text.capitalize() 例:Python
前方一致 text.startswith("Py") True / False
後方一致 text.endswith("on") True / False
数字だけか text.isdigit() True / False
英数字だけか text.isalnum() True / False

f文字列

name = "Cake"
price = 1200

message = f"{name}さんの商品価格は{price:,}円です"
# Cakeさんの商品価格は1,200円です

説明するときの一言
str は文字列型です。添字やスライスで一部を取得できますが、元の文字列自体は直接変更できません。


4. リスト:list

リストは、順序を保ちながら複数の値をまとめ、後から変更できる型です。異なる型を混在させることもできます。

items = ["apple", "banana", "orange"]
empty = []

4-1. 参照・スライス

items[0]        # "apple"
items[-1]       # "orange"
items[1:3]      # ["banana", "orange"]
items[:2]       # ["apple", "banana"]
items[::2]      # 1つ飛ばし
items[::-1]     # 逆順の新しいリスト
len(items)      # 要素数

存在しない位置を items[99] のように指定すると IndexError(インデックスエラー)になります。

4-2. 追加・結合

操作 コード 動作
末尾へ1要素追加 items.append("grape") 渡した値を1要素として追加
複数要素を追加 items.extend(["grape", "melon"]) 各要素を展開して追加
指定位置へ追加 items.insert(1, "grape") 位置1へ挿入
新しいリストを作る items + ["grape"] 元のリストは変えない
繰り返す [0] * 3 [0, 0, 0]
items = ["apple"]
items.append(["banana", "orange"])
# ["apple", ["banana", "orange"]]

items = ["apple"]
items.extend(["banana", "orange"])
# ["apple", "banana", "orange"]

append() は「1つとして追加」、extend() は「中身を展開して追加」です。

4-3. 更新

items = ["apple", "banana", "orange"]

items[1] = "melon"
# ["apple", "melon", "orange"]

items[0:2] = ["grape", "peach"]
# ["grape", "peach", "orange"]

4-4. 削除

操作 コード 動作・注意
値を指定して削除 items.remove("banana") 最初に一致した1件を削除。なければ ValueError
位置を指定して削除 items.pop(1) 削除した値を返す
末尾を削除 items.pop() 最後の値を返す
位置・範囲を削除 del items[1] / del items[1:3] 戻り値なし
全件削除 items.clear() 空リストにする

安全に値を削除する例:

if "banana" in items:
    items.remove("banana")

4-5. 検索・集計

"apple" in items           # 含まれるか
"apple" not in items       # 含まれないか
items.index("apple")        # 最初の位置。なければValueError
items.count("apple")        # 個数
len(items)                  # 要素数
min([3, 1, 8])              # 1
max([3, 1, 8])              # 8
sum([3, 1, 8])              # 12

4-6. 並べ替え

numbers = [3, 1, 10, 2]

numbers.sort()                       # 元のリストを昇順に変更
numbers.sort(reverse=True)           # 元のリストを降順に変更
new_numbers = sorted(numbers)        # 新しいリストを返す
numbers.reverse()                    # 現在の並びを逆転
users = [
    {"name": "Cake", "age": 40},
    {"name": "Cookie", "age": 20},
]

users.sort(key=lambda user: user["age"])
  • list.sort():元のリストを変更し、戻り値は None
  • sorted():元のデータを変更せず、新しいリストを返す

4-7. 繰り返し処理

for item in items:
    print(item)

for index, item in enumerate(items):
    print(index, item)

enumerate(エニュメレート)は、位置と値を同時に取得します。

names = ["Cake", "Cookie"]
ages = [40, 25]

for name, age in zip(names, ages):
    print(name, age)

zip(ジップ)は、複数の反復可能オブジェクトを同じ位置ごとに組み合わせます。

4-8. リスト内包表記

numbers = [1, 2, 3, 4, 5]

squares = [number ** 2 for number in numbers]
# [1, 4, 9, 16, 25]

even_squares = [number ** 2 for number in numbers if number % 2 == 0]
# [4, 16]

基本形:

[変換後の値 for 要素 in 元データ if 条件]

複雑になりすぎる場合は、通常の for 文の方が読みやすくなります。

4-9. コピーの注意

a = [1, 2, 3]
b = a
b.append(4)

print(a)    # [1, 2, 3, 4]

b = a はコピーではなく、同じリストを参照します。

a = [1, 2, 3]
b = a.copy()       # または a[:]、list(a)
b.append(4)

print(a)           # [1, 2, 3]

入れ子のリストを完全に分けたい場合は、ディープコピーを使います。

from copy import deepcopy

original = [[1, 2], [3, 4]]
copied = deepcopy(original)
  • copy():シャローコピー(shallow copy/シャローコピー)。外側だけ別物
  • deepcopy():ディープコピー(deep copy/ディープコピー)。内側も再帰的に別物

4-10. リスト操作の注意点

反復中に元のリストを変更しない

numbers = [1, 2, 3, 4]

# 新しいリストを作る方が安全
numbers = [number for number in numbers if number % 2 == 0]

入れ子リストの初期化

# 注意:3行が同じ内側リストを参照する
bad = [[0] * 3] * 3
bad[0][0] = 1
# [[1, 0, 0], [1, 0, 0], [1, 0, 0]]

# 各行を別々に作る
safe = [[0] * 3 for _ in range(3)]

スタックとキュー

stack = []
stack.append("A")
stack.append("B")
stack.pop()              # "B"

リストはスタックに使えます。先頭から頻繁に削除するキューでは、collections.deque(デック)が効率的です。

from collections import deque

queue = deque(["A", "B"])
queue.append("C")
queue.popleft()          # "A"

説明するときの一言
リストは、順序のある複数の値を保持し、追加・更新・削除できる可変コレクションです。


5. タプル:tuple

タプルは、順序を保つが、作成後に中身を変更できない型です。

point = (10, 20)
empty = ()
single = (10,)       # 1要素では末尾のカンマが必要

主な操作

point[0]              # 10
point[0:2]            # (10, 20)
len(point)            # 2
point.count(10)       # 1
point.index(20)       # 1

アンパック

x, y = (10, 20)

first, *middle, last = (1, 2, 3, 4)
# first = 1, middle = [2, 3], last = 4

x, y = y, x           # 値の入れ替え

利用場面

  • 変更されたくない値の組
  • 関数から複数の値を返す
  • 辞書のキーとして使う
  • 座標やRGB値など、意味のまとまりを表す

タプルの各要素も辞書のキーにできる型である必要があります。リストを含むタプルはキーにできません。

説明するときの一言
タプルは、リストに似ていますが、作成後に中身を変更できないため、固定した値の組に向いています。


6. 辞書:dict

辞書は、キー(key/キー)と値(value/バリュー)を対応づけて管理する型です。

user = {
    "name": "Cake",
    "age": 40,
    "skills": ["Python", "Java"],
}

empty = {}

Python 3.7以降、辞書は挿入順を保持します。ただし、位置番号ではなくキーで値を扱うのが基本です。

6-1. 取得

user["name"]              # "Cake"
user.get("age")           # 40
user.get("email")         # None
user.get("email", "未登録") # "未登録"
書き方 キーがない場合
user["email"] KeyError(キーエラー)
user.get("email") None
user.get("email", "未登録") 指定した既定値

値が None なのか、キー自体がないのかを区別したい場合は in を使います。

if "email" in user:
    print(user["email"])

6-2. 追加・更新・結合

user["email"] = "Cake@example.com"   # 新規追加
user["age"] = 39                     # 更新

user.update({"age": 50, "city": "Tokyo"})

Python 3.9以降は | で新しい辞書を作れます。

base = {"name": "Cake", "age": 40}
extra = {"age": 50, "city": "Tokyo"}

merged = base | extra
# 同じキーは右側の値が優先される

元の辞書を更新する場合:

base |= extra

6-3. キーがない場合だけ初期値を入れる

user.setdefault("role", "member")

setdefault()(セットデフォルト)は、キーがあれば既存値を返し、なければ指定値を登録して返します。

groups = {}
for name, team in [("Cake", "A"), ("Cookie", "B"), ("Ice", "A")]:
    groups.setdefault(team, []).append(name)

# {"A": ["Cake", "Ice"], "B": ["Cookie"]}

6-4. 削除

操作 コード 動作・注意
キーを指定して削除 del user["age"] なければ KeyError
削除して値を取得 user.pop("age") なければ KeyError
既定値つきで削除 user.pop("age", None) なければ既定値
最後の組を削除 user.popitem() (キー, 値) を返す
全件削除 user.clear() 空辞書にする

6-5. キー・値・組の取得

user.keys()       # キーのビュー
user.values()     # 値のビュー
user.items()      # (キー, 値)のビュー

これらはリストではなく、辞書の変更を反映するビューオブジェクトです。リストが必要なら変換します。

keys = list(user.keys())

6-6. 繰り返し処理

# キーを取得
for key in user:
    print(key)

# 値を取得
for value in user.values():
    print(value)

# キーと値を取得
for key, value in user.items():
    print(key, value)

6-7. 検索・件数

"name" in user          # キーに存在するか
"Cake" in user.values()  # 値に存在するか
len(user)                # キーと値の組の数

in user は、値ではなくキーを検索します。

6-8. 辞書内包表記

numbers = [1, 2, 3, 4]

squares = {number: number ** 2 for number in numbers}
# {1: 1, 2: 4, 3: 9, 4: 16}

even_squares = {
    number: number ** 2
    for number in numbers
    if number % 2 == 0
}
# {2: 4, 4: 16}

基本形:

{キー:  for 要素 in 元データ if 条件}

6-9. 並べ替え

辞書自体ではなく、キーまたは (キー, 値) を並べ替えます。

scores = {"Cake": 80, "Cookie": 95, "Ice": 70}

sorted(scores)                         # キーで昇順
sorted(scores.items())                 # キーで昇順
sorted(scores.items(), key=lambda item: item[1])
sorted(scores.items(), key=lambda item: item[1], reverse=True)

並べ替えた辞書を作る例:

sorted_scores = dict(
    sorted(scores.items(), key=lambda item: item[1], reverse=True)
)

6-10. 入れ子の辞書

user = {
    "name": "Cake",
    "address": {
        "prefecture": "Tokyo",
        "city": "Shinjuku",
    },
}

city = user["address"]["city"]

キーがない可能性を考慮する例:

city = user.get("address", {}).get("city", "未登録")

6-11. 辞書のキーにできるもの

キーには、基本的にハッシュ可能(hashable/ハッシャブル)な変更不能オブジェクトを使います。

使える例:

mapping = {
    "name": "Cake",     # str
    1: "one",           # int
    (10, 20): "point",  # tuple
}

使えない例:

# {[1, 2]: "value"}   # listは変更可能なのでTypeError
# {{"a": 1}: "value"}  # dictもキーにできない
  • キーは重複できない
  • 同じキーを再登録すると、後の値で上書きされる
  • 値は重複してよい

6-12. コピーの注意

original = {"name": "Cake", "skills": ["Python"]}
shallow = original.copy()
shallow["skills"].append("Java")

print(original["skills"])  # ["Python", "Java"]

dict.copy() はシャローコピーなので、入れ子のリストや辞書は共有されます。

from copy import deepcopy

copied = deepcopy(original)

6-13. よく使う補助クラス

defaultdict(デフォルトディクト)

キーがない場合の初期値を自動生成します。

from collections import defaultdict

groups = defaultdict(list)
groups["A"].append("Cake")
groups["A"].append("Ice")

Counter(カウンター)

要素の出現回数を数えます。

from collections import Counter

counts = Counter(["apple", "apple", "banana"])
print(counts["apple"])   # 2
print(counts.most_common(1))

6-14. 辞書操作の注意点

反復中にキー数を変更しない

scores = {"Cake": 80, "Cookie": 40, "Ice": 70}

for name in list(scores):
    if scores[name] < 60:
        del scores[name]

fromkeys() と変更可能な初期値

keys = ["A", "B"]
bad = dict.fromkeys(keys, [])
bad["A"].append(1)

print(bad)   # {"A": [1], "B": [1]}

同じリストが共有されるため、個別に作る場合は内包表記を使います。

safe = {key: [] for key in keys}

一言
辞書は、名前やIDなどのキーを使って値を管理する可変コレクションです。位置ではなく、意味のあるキーで値を取得できます。


7. 集合:set

集合は、重複しない値をまとめる型です。順序や添字での参照を目的には使いません。

numbers = {1, 2, 3}
empty = set()           # {} は空の辞書になる

主な操作

numbers.add(4)               # 1要素追加
numbers.update([4, 5])       # 複数追加
numbers.remove(3)            # なければKeyError
numbers.discard(99)          # なくてもエラーにならない
numbers.pop()                # 任意の1要素を削除して返す
numbers.clear()              # 全件削除

集合演算

a = {1, 2, 3}
b = {3, 4, 5}

a | b       # 和集合 {1, 2, 3, 4, 5}
a & b       # 積集合 {3}
a - b       # 差集合 {1, 2}
a ^ b       # 対称差 {1, 2, 4, 5}
a <= b      # 部分集合か
a >= b      # 上位集合か

リストから重複を除く例:

unique_numbers = list(set([1, 1, 2, 3]))

元の順序を保って重複を除く場合は list(dict.fromkeys(values)) を使えます。


8. 日付と時刻:datedatetime

datetime(デートタイム)は、標準ライブラリのモジュール名であり、その中のクラス名でもあります。

from datetime import date, datetime, timedelta
  • date:日付だけ
  • datetime:日付と時刻
  • timedelta(タイムデルタ):時間差・期間

作成・現在日時

today = date.today()
now = datetime.now()

birthday = date(1990, 4, 1)
meeting = datetime(2026, 7, 20, 10, 30)

各要素の取得

meeting.year       # 2026
meeting.month      # 7
meeting.day        # 20
meeting.hour       # 10
meeting.minute     # 30
meeting.weekday()  # 月曜=0 ~ 日曜=6

文字列へ変換:strftime

strftime(ストラフタイム)は、日時を指定形式の文字列へ変換します。

text = meeting.strftime("%Y-%m-%d %H:%M")
# "2026-07-20 10:30"

文字列から変換:strptime

strptime(ストリップタイム)は、文字列を日時へ変換します。

meeting = datetime.strptime("2026-07-20 10:30", "%Y-%m-%d %H:%M")

主な書式

記号 意味
%Y 4桁の年 2026
%m 2桁の月 07
%d 2桁の日 20
%H 24時間表記の時 10
%M 30
%S 05

加算・減算・比較

tomorrow = today + timedelta(days=1)
one_hour_later = now + timedelta(hours=1)

start = datetime(2026, 7, 20, 10, 0)
end = datetime(2026, 7, 20, 12, 30)

difference = end - start
print(difference.total_seconds())  # 9000.0

if start < end:
    print("startの方が先")

タイムゾーン

from datetime import datetime
from zoneinfo import ZoneInfo

jst_now = datetime.now(ZoneInfo("Asia/Tokyo"))
  • ナイーブ(naive/ナイーブ):タイムゾーン情報なし
  • アウェア(aware/アウェア):タイムゾーン情報あり

タイムゾーンあり・なしの datetime を混在させて比較しないようにします。

一言
date は日付、datetime は日付と時刻、timedelta はその差や期間を扱います。


9. オブジェクト指向

OOP(オー・オー・ピー/Object-Oriented Programming:オブジェクト指向プログラミング)は、データと、そのデータを操作する処理をオブジェクトとしてまとめる考え方です。

クラスとインスタンス

  • クラス:設計図・型
  • インスタンス:クラスから生成された具体的な実体
class Product:
    tax_rate = 0.10  # クラス変数

    def __init__(self, name, price):
        self.name = name    # インスタンス変数
        self.price = price  # インスタンス変数

    def total_price(self):  # インスタンスメソッド
        return round(self.price * (1 + self.tax_rate))


book = Product("Python入門", 2000)  # インスタンス生成
print(book.name)                     # Python入門
print(book.total_price())            # 2200

変数の種類

種類 有効範囲・特徴
ローカル変数 total = 100 関数・メソッド内で使う
インスタンス変数 self.name インスタンスごとに異なる値を持つ
クラス変数 Product.tax_rate クラス全体で共有する

リストなどの変更可能な値をクラス変数にすると、全インスタンスで共有されるため注意します。

メソッドの種類

class Product:
    category = "book"

    def __init__(self, name):
        self.name = name

    def display_name(self):
        # インスタンスメソッド:selfで個別データを扱う
        return self.name

    @classmethod
    def category_name(cls):
        # クラスメソッド:clsでクラスを扱う
        return cls.category

    @staticmethod
    def is_valid_name(name):
        # スタティックメソッド:selfもclsも不要
        return bool(name.strip())
  • self(セルフ):そのメソッドを呼び出したインスタンス
  • cls(クラス):そのメソッドを呼び出したクラス

オブジェクト指向の三要素

要素 読み方 意味 主な効果
カプセル化 encapsulation(エンカプセレーション) データと処理をまとめ、内部の扱いを制御する 変更箇所を限定し、不正な状態を防ぐ
継承 inheritance(インヘリタンス) 既存クラスの性質を引き継ぐ 共通化・再利用・拡張
ポリモーフィズム polymorphism(ポリモーフィズム)/多態性 同じ呼び出し方で、対象ごとに異なる処理を行う 呼び出し側の分岐を減らす

資料によっては「抽象化」を含めて四大要素と説明する場合もありますが、ここでは、参考書などでよく使われる三要素で整理しています。

1. カプセル化

class BankAccount:
    def __init__(self, balance):
        self._balance = balance  # 外部から直接変更しないという慣例

    @property
    def balance(self):
        return self._balance

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("入金額は1円以上にしてください")
        self._balance += amount

Pythonの _name は「外部から直接使わない」という慣例です。完全なアクセス禁止ではありません。

2. 継承

既存クラスの共通機能を、別のクラスへ引き継ぎます。

3. ポリモーフィズム

class Dog:
    def speak(self):
        return "ワン"


class Cat:
    def speak(self):
        return "ニャー"


for animal in [Dog(), Cat()]:
    print(animal.speak())

呼び出し側はどの動物かを細かく分岐せず、共通して speak() を呼べます。

説明するときの一言
オブジェクト指向は、関連するデータと処理をクラスにまとめ、実体であるインスタンスを作って扱う設計方法です。


10. __init____main__ 形は似てるけど

両方とも前後に二重アンダースコアがつきますが、役割はまったく異なります。

項目 読み方 正体 役割
__init__ ダンダー・イニット 特殊メソッド インスタンスの初期値を設定する
__main__ ダンダー・メイン 実行中モジュールの特別な名前 直接実行されたファイルを示す

dunder(ダンダー)は、double underscore(ダブル・アンダースコア)の略称です。

__init__

class User:
    def __init__(self, name):
        self.name = name


user = User("Cake")
  • User(...) でインスタンスを作るときに呼ばれる
  • インスタンス変数の初期値を設定する
  • 厳密には、インスタンスを作るのは __new__、初期化するのが __init__
  • __init__ は値を返さない。return で値を返すと TypeError

__init__.py との違い

__init__.py は、ディレクトリをPythonパッケージとして扱う際に使われるファイルです。クラスの __init__ メソッドとは別物です。

__main__

def main():
    print("処理開始")


if __name__ == "__main__":
    main()
  • ファイルを直接実行した場合:__name__"__main__"
  • 他のファイルからインポートされた場合:__name__ はモジュール名
  • インポート時にだけ実行したくない処理を分けられる
  • main() という関数名自体は慣例であり、Pythonで必須ではない

例:

# sample.py を直接実行
python sample.py
# このとき、sample.py 内では __name__ == "__main__"
# 別ファイルから読み込む
import sample

print(sample.__name__)  # "sample"

一言
__init__ はインスタンスの初期化処理、__main__ はファイルが直接実行されたかを判定するための特別なモジュール名です。


11. 継承・オーバーライド・多重継承

スーパークラスとサブクラス

  • スーパークラス(superclass/スーパークラス):継承元・親クラス・基底クラス
  • サブクラス(subclass/サブクラス):継承先・子クラス・派生クラス
class Animal:  # スーパークラス
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "鳴き声"


class Dog(Animal):  # サブクラス
    def __init__(self, name, breed):
        super().__init__(name)
        self.breed = breed

    def speak(self):
        return "ワン"

super()

super(スーパー)は、MRO(エム・アール・オー/Method Resolution Order:メソッド解決順序)に従って、次のクラスの処理を呼び出します。

dog = Dog("Pochi", "Shiba")
print(dog.name)
print(dog.speak())

オーバーライド

オーバーライド(override/オーバーライド)は、スーパークラスと同名のメソッドをサブクラスで定義し、処理を上書きすることです。

class Cat(Animal):
    def speak(self):
        return "ニャー"

継承を使うメリット

  • 共通処理を1か所へまとめられる
  • 重複コードを減らせる
  • スーパークラス型として共通に扱える
  • サブクラスごとの差分だけ実装できる
  • ポリモーフィズムを利用できる

継承を使う判断

継承は「サブクラスはスーパークラスの一種である」という is-a(イズ・ア)関係のときに向いています。

  • Dog is an Animal:自然
  • Car is an Engine:不自然

部品として利用する has-a(ハズ・ア)関係なら、継承よりコンポジション(composition/コンポジション、委譲・組み合わせ)が適しています。

class Engine:
    def start(self):
        return "engine started"


class Car:
    def __init__(self):
        self.engine = Engine()  # Car has an Engine

多重継承

多重継承は、1つのクラスが複数のクラスを継承することです。

class Flyable:
    def fly(self):
        return "飛ぶ"


class Swimmable:
    def swim(self):
        return "泳ぐ"


class Duck(Flyable, Swimmable):
    pass


duck = Duck()
print(duck.fly())
print(duck.swim())

多重継承の注意

  • 同名メソッドがある場合はMROで呼び出し順が決まる
  • super() は単純な「親クラス指定」ではなく、MRO上の次のクラスを呼ぶ
  • 菱形継承では処理順が分かりにくくなりやすい
  • 小さな機能を追加するMixin(ミックスイン)として使うと整理しやすい
print(Duck.mro())
# メソッドを探す順番を確認できる

説明するときの一言
継承は共通機能を引き継ぐ仕組み、オーバーライドは子クラスで処理を差し替える仕組み、多重継承は複数クラスの機能を引き継ぐ仕組みです。


12. コールスタック・スタックトレース

スタック

スタック(stack/スタック)は、後から入れたものを先に取り出すデータ構造です。

LIFO(ライフォ/Last In, First Out:後入れ先出し)と呼びます。

コールスタック

コールスタック(call stack/コールスタック)は、実行中の関数呼び出しを管理する仕組みです。

main() を呼ぶ
  └─ calculate() を呼ぶ
       └─ divide() を呼ぶ
  • 関数を呼ぶと、実行情報であるフレームが積まれる
  • 関数が終了すると、そのフレームが取り除かれる
  • 現在実行中の最も深い関数がスタックの一番上にある
def divide(a, b):
    return a / b


def calculate():
    return divide(10, 0)


def main():
    calculate()


main()

スタックトレース

スタックトレース(stack trace/スタックトレース)は、例外発生までにどの関数を通ったかを示す記録です。Pythonでは traceback(トレースバック)とも呼びます。

Traceback (most recent call last):
  File "app.py", line 13, in <module>
    main()
  File "app.py", line 10, in main
    calculate()
  File "app.py", line 6, in calculate
    return divide(10, 0)
  File "app.py", line 2, in divide
    return a / b
ZeroDivisionError: division by zero

スタックトレースの見方

  1. 一番下の例外名とメッセージを読む
    ZeroDivisionError: division by zero
  2. そのすぐ上のファイル名・行番号・コードを見る
    実際に例外が発生した場所に近い
  3. 下から上へ呼び出し元をたどる
    どの処理経由でその行へ来たか確認する
  4. 自分が書いたファイルを優先して確認する
    ライブラリ内部の行より、最初に渡した不正な値を探す
  5. 例外の原因となった変数の値・型を確認する

Pythonの表示順は、上が古い呼び出し、下が例外発生に近い呼び出しです。そのため、基本は一番下から読みます。

ログへトレースバックを出す

import logging

try:
    result = 10 / 0
except ZeroDivisionError:
    logging.exception("計算処理に失敗しました")

logging.exception()(ロギング・エクセプション)は、except ブロック内で使うとスタックトレースも記録します。

説明するときの一言
コールスタックは関数の呼び出し履歴、スタックトレースは例外発生時にその履歴を表示したものです。


13. 例外処理

一般的な例外

例外 読み方 主な原因
SyntaxError シンタックスエラー 文法が不正
IndentationError インデンテーションエラー インデントが不正
NameError ネームエラー 未定義の名前を使用
UnboundLocalError アンバウンドローカルエラー ローカル変数へ代入前に参照
TypeError タイプエラー 型に合わない操作・引数
ValueError バリューエラー 型は正しいが値が不正
AttributeError アトリビュートエラー 存在しない属性・メソッド
KeyError キーエラー 辞書にキーがない
IndexError インデックスエラー リスト等の位置が範囲外
ZeroDivisionError ゼロディビジョンエラー 0で除算
FileNotFoundError ファイルノットファウンドエラー ファイルが存在しない
PermissionError パーミッションエラー 権限がない
ModuleNotFoundError モジュールノットファウンドエラー モジュールが見つからない
AssertionError アサーションエラー assert の条件が偽
TimeoutError タイムアウトエラー 処理が規定時間を超えた

TypeErrorValueError の違い

len(100)        # TypeError:この型にはlenを使えない
int("abc")     # ValueError:str型は受け取れるが、内容を整数化できない

try / except

def calculate(text):
    try:
        number = int(text)
        result = 100 / number
    except ValueError as error:
        print(f"整数へ変換できません: {error}")
    except ZeroDivisionError:
        print("0では割れません")
    else:
        print(f"計算結果: {result}")
    finally:
        print("処理終了")
キーワード 役割
try 例外が発生する可能性のある処理
except 指定した例外が発生した場合の処理
else 例外が発生しなかった場合だけ実行
finally 例外の有無にかかわらず最後に実行

raise

raise は、意図的に例外を発生させます。

def register_age(age):
    if age < 0:
        raise ValueError("年齢は0以上で指定してください")
    return age

捕捉後に同じ例外を再送出する

import logging

try:
    result = 100 / 0
except ZeroDivisionError:
    logging.exception("計算に失敗しました")
    raise

引数なしの raise は、現在処理中の例外をそのまま上位へ送ります。

例外を変換し、原因を残す

class OrderError(Exception):
    pass


def load_order(order_id):
    try:
        return int(order_id)
    except ValueError as error:
        raise OrderError("注文IDが不正です") from error

raise ... from ... により、元の例外との因果関係をスタックトレースに残せます。

独自例外

class InsufficientStockError(Exception):
    """在庫不足を表す例外。"""


def purchase(stock, quantity):
    if quantity > stock:
        raise InsufficientStockError("在庫が不足しています")

finally と後処理

file = None
try:
    file = open("sample.txt", encoding="utf-8")
    print(file.read())
finally:
    if file is not None:
        file.close()

ファイルのようなリソースは、通常 with 文を使う方が安全です。

with open("sample.txt", encoding="utf-8") as file:
    print(file.read())

例外処理の注意

  • except: だけで全例外をまとめて捕捉しない
  • 可能な限り具体的な例外型を捕捉する
  • try の範囲を必要最小限にする
  • 例外を握りつぶさず、処理・記録・再送出のいずれかを行う
  • finally 内で return しない。元の例外や戻り値を隠す可能性がある
  • Exception は通常のアプリケーション例外の基底クラス
  • KeyboardInterruptSystemExit まで一括捕捉する BaseException は通常捕捉しない
  • クリーンアップ目的なら、可能な場合は with 文を優先する

説明するときの一言
例外処理は、異常発生時にプログラムをただ停止させるのではなく、記録・代替処理・後片付け・上位への通知を行う仕組みです。


14. まとめ

データ型

int は整数、float は小数、str は文字列です。
list は変更できる順序付きの集まり、tuple は変更できない順序付きの集まりです。
dict はキーと値の対応、set は重複しない値の集合を扱います。
date は日付、datetime は日付と時刻を扱います。

リストと辞書の違い

リストは「何番目か」という位置で値を扱い、辞書は「名前やIDなどのキー」で値を扱います。
順番に並べたデータはリスト、項目名と値を対応づけたいデータは辞書が適しています。

# リスト:位置で取得
products = ["book", "pen"]
print(products[0])

# 辞書:キーで取得
product = {"name": "book", "price": 1200}
print(product["name"])

オブジェクト指向

クラスは設計図、インスタンスは設計図から作った実体です。
データをインスタンス変数、処理をメソッドとしてまとめます。
三大要素は、内部を守るカプセル化、共通機能を引き継ぐ継承、同じ呼び出しで異なる動きを実現するポリモーフィズムです。

__init____main__

__init__ はインスタンス作成時の初期化メソッドです。
__main__ はそのPythonファイルが直接実行されたことを示す特別なモジュール名です。

スタックトレース

スタックトレースは、例外発生までに通った関数と行番号の履歴です。
一番下の例外名とメッセージを確認し、その直上の発生箇所から上へたどります。

例外処理

try に失敗する可能性のある処理、except に例外発生時の処理を書きます。
else は成功時、finally は成功・失敗にかかわらず最後に実行されます。
raise は、異常を検知した側から明示的に例外を通知するために使います。


最低限覚えたいコード

from datetime import datetime


def main():
    users = [
        {"name": "Cake", "score": 80},
        {"name": "Cookie", "score": 95},
    ]

    try:
        high_scores = [user for user in users if user["score"] >= 90]

        for user in high_scores:
            print(f"{user['name']}: {user['score']}")

        print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    except KeyError as error:
        print(f"必要なキーがありません: {error}")


if __name__ == "__main__":
    main()
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?