Python講座 / クラスとインスタンスの基本
クラスは関連するデータと処理をまとめる定義で、インスタンスはその定義から作る個々のオブジェクトです。同じクラスのインスタンスでも、それぞれ独立した名前や金額を保持できます。
定義と個々のオブジェクトを区別する
Expenseは支出を表す型の定義で、昼食とバス代はその個別のインスタンスです。属性に状態を保存し、メソッドでその状態に関係する処理を表します。単純な計算をすべてクラスへ変える必要はありません。
インスタンスメソッドの最初の引数selfには、呼び出した対象が渡されます。selfは慣例的な名前です。__init__は作成されたインスタンスを初期化します。通常のfirst.describe()という呼び出しでselfを手動で渡す必要はありません。
属性とアクセス規則は、インスタンス属性とクラス属性で扱う規則とつながります。
二つの支出を作って実行する
classes_demo.pyへ次の全体を保存し、仮想環境でpython classes_demo.pyを実行します。金額の単位は例を通して韓国ウォン(KRW)です。
class Expense:
def __init__(self, name, amount):
if amount < 0:
raise ValueError("negative amount")
self.name = name
self.amount = amount
def describe(self):
return f"{self.name}: {self.amount:,} KRW"
first = Expense("lunch", 8000)
second = Expense("bus", 2500)
print(first.describe())
print(second.describe())
print(first.amount + second.amount)
予想結果は次のとおりです。表示処理は共通でも、参照するnameとamountは呼び出したインスタンスのものです。
lunch: 8,000 KRW bus: 2,500 KRW 10500
初期化と責務の範囲を決める
この初期化は金額が負でないことを調べますが、入力が数値であることを前提としています。文字列、bool、小数も扱うなら、受け入れる型と単位の規則を別に定めてください。初期化時に正しくても、後からfirst.amount = -1を代入すると、この検査は働きません。
支出の計算、ファイル保存、ネットワーク通信、画面表示を一つのクラスへ詰め込むと変更理由が増えます。支出そのものの規則と、保存方法などの外部とのやり取りを分けると、個別に確認しやすくなります。
独立性と更新時の規則を確認する
first.amountだけを9000へ変更し、second.amountが2500のままであることを確かめます。負の値で新しいExpenseを作るとValueErrorになることも確認し、最後に元の値へ戻します。
Expense.describe(first)とfirst.describe()の結果を比較すると、束縛された呼び出しの意味を確認できます。属性名の誤字で別の属性を作ることがあるため、命名とテストが重要です。型ヒント、dataclass、テストは役割が異なります。更新時にも規則を守らせる方法はプロパティで扱います。
selfはそのメソッドを呼び出されたインスタンスです。同じクラスから作った二つのオブジェクトも、別々のインスタンス属性を持てます。名前→オブジェクト→その属性という関係で読むと、呼び出し時にselfがどの対象を指すか追えます。
| 名前 | 別のオブジェクト | インスタンス属性 |
|---|---|---|
| first | object A | first.amount = 3500 |
| second | object B | second.amount = 8000 |
表のfirstとsecondは関係を示すための名前です。一方のインスタンス属性を変えても他方の属性は変わりません。




