クラスの要点
内容の確認日: 2026-10-04
この分野は「Pythonチュートリアル」の第 9 章 (クラス) に対応します。クラスの定義とインスタンスの作り方、インスタンス変数とクラス変数の違い、継承の仕組みが問われます。
Python のクラスは、ほかの言語に比べて制約が少なく、インスタンスに後から属性を追加できたり、private のようなアクセス制限がなかったりします。こうした Python らしい仕様が、問題の引っかけになります。
クラスの定義とインスタンス
クラスは class クラス名: で定義します。インスタンスを作るときは クラス名(引数) と書き、そのとき初期化メソッド __init__ が呼ばれます。
メソッドの最初の引数には、慣習として self という名前を付けます。self には、メソッドを呼び出したインスタンス自身が自動的に渡されます (a.add(x) は Dog.add(a, x) と同じ)。インスタンス変数は self.name = name のように self に属性を代入して作ります。
インスタンス変数とクラス変数
クラスの直下で代入した変数はクラス変数で、すべてのインスタンスで共有されます。self.xxx に代入したインスタンス変数は、インスタンスごとに別々です。
クラス変数にリストのような変更できる値を入れると、どのインスタンスから append しても同じリストが変わります。インスタンスごとに持たせたい値は、__init__ の中でインスタンス変数として作ります。
また、インスタンスを通してクラス変数に代入すると、クラス変数は変わらず、そのインスタンスに同じ名前のインスタンス変数が新しく作られます。
class Dog: kind = "犬" tricks = [] def __init__(self, name): self.name = name self.toys = [] def add(self, trick, toy): self.tricks.append(trick) self.toys.append(toy)a = Dog("Pochi")b = Dog("Hachi")a.add("お手", "ボール")b.add("伏せ", "ロープ")print(a.kind, b.name, a.toys, b.toys)print(a.tricks is b.tricks, a.tricks)a.kind = "柴犬"print(a.kind, b.kind, Dog.kind)python3 main.py 犬 Hachi ['ボール'] ['ロープ'] True ['お手', '伏せ'] 柴犬 犬 犬
継承とオーバーライド
class 子クラス(親クラス): で、親クラスを継承したクラスを作れます。子クラスで同じ名前のメソッドを定義すると、親のメソッドをオーバーライドします。呼び出されるのは、インスタンスの実際のクラスのメソッドです。親クラスのメソッドの中から呼んだメソッドも、子クラスでオーバーライドしたものが使われます。
子クラスから親クラスのメソッドを呼ぶには super() を使います。子クラスで __init__ を定義した場合、親の __init__ は自動では呼ばれないので、super().__init__(...) で明示的に呼びます。
__str__ メソッドを定義すると、print() や str() で使われる文字列を決められます。
Python では、インスタンスに後から新しい属性を追加できます。一方、存在しない属性やメソッドを使うと AttributeError です。
class Animal: def __init__(self, name): self.name = name def speak(self): return "..." def introduce(self): return f"{self.name}: {self.speak()}"class Cat(Animal): def __init__(self, name, color): super().__init__(name) self.color = color def speak(self): return "ニャー" def __str__(self): return f"Cat({self.name}, {self.color})"c = Cat("Tama", "白")print(c.introduce())print(c)print(isinstance(c, Animal), issubclass(Animal, Cat))c.age = 3print(c.age)print(c.fly())python3 main.py Tama: ニャー Cat(Tama, 白) True False 3
例外が発生: AttributeError
isinstance(obj, クラス) は、obj がそのクラス (またはそのサブクラス) のインスタンスかを、issubclass(子, 親) はクラスの継承関係を調べます。class C(A, B): のように複数のクラスを継承する多重継承もでき、属性は基本的に左の親クラスから順に探されます。
名前の先頭のアンダースコア
Python には private のような、外からのアクセスを禁止する仕組みはありません。代わりに、次の慣習・仕組みがあります。
・_items (アンダースコア 1 つ): 「内部用なので外から使わないでほしい」という慣習。アクセスはできる
・__balance (アンダースコア 2 つ): 名前修飾 (name mangling) により、クラスの外からは _クラス名__balance という名前に変わる。サブクラスとの名前の衝突を避けるための仕組み
class Account: def __init__(self): self._note = "内部用" self.__balance = 100a = Account()print(a._note, a._Account__balance)print(a.__balance)python3 main.py 内部用 100
例外が発生: AttributeError
イテレータとジェネレータ
for 文は、内部で iter() でイテレータを作り、next() で要素を 1 つずつ取り出しています。要素がなくなると StopIteration 例外が起き、for 文はそれを合図にループを終えます。
関数の中で yield を使うと、その関数はジェネレータになります。ジェネレータは、yield のたびに値を 1 つ返して一時停止し、次の値を求められると続きから実行します。sum(x * x for x in range(4)) のようなジェネレータ式でも作れます。
def countdown(n): while n > 0: yield n n -= 1print(list(countdown(3)), sum(x * x for x in range(4)))it = iter("ab")print(next(it), next(it))next(it)python3 main.py [3, 2, 1] 14 a b
例外が発生: StopIteration
試験でよくある引っかけ
selfを書き忘れるメソッドの最初の引数
selfを書き忘れると、呼び出したときに引数の数が合わずTypeErrorになります。クラス変数のリスト
クラス変数のリストは全インスタンスで共有されます。インスタンスごとのリストは
__init__で作ります。インスタンスからクラス変数に代入
a.kind = "柴犬"はクラス変数を変えず、aにインスタンス変数を作ります。b.kindは元のままです。親の
__init__子クラスで
__init__を定義すると、親の__init__は自動では呼ばれません。super().__init__(...)で呼びます。インスタンスメソッドをクラスから呼ぶ
C.show()のようにインスタンスなしで呼ぶと、selfに渡すものがなくTypeErrorです。アンダースコア 2 つの名前
__balanceはクラスの外からa.__balanceでは使えず (AttributeError)、a._Account__balanceという名前になります。
問題で確認する
この分野の問題を、解説つきで読めます (登録不要)。
出典・参考
コード例は、実際に実行して結果を確認しています。