0-15では return とスコープを学びました。今回のテーマ「クラス」は、それをもう一段進めた考え方です。用語が多く、最初は面食らうかもしれません。まず言葉の意味を整理してから、ブロックを順に確認しましょう。

まずはPycoBlocksを開こう
下のPycoBlocksで直接作業するか、別タブで開き、生成されるPythonコードを見ながら進めてください。
まず用語を整理しよう
クラスには専門用語が6つ出てきます。今は「なんとなくそういうものか」程度でかまいません。ブロックを動かすうちに、自然とわかってきます。
| 用語 | 読み方 | 一言で言うと |
|---|---|---|
| クラス | クラス | データと処理をまとめた「設計図」 |
| インスタンス | インスタンス | 設計図から作った「実体」 |
| 属性 | ぞくせい | インスタンスが持つデータ(self.〇〇 で書く) |
| メソッド | メソッド | クラスの中に定義する「関数」のこと |
| self | セルフ | 「自分自身のインスタンス」を指す特別な変数 |
| __init__ | ダンダーイニット | インスタンスを作るとき自動で呼ばれる特別なメソッド |
これらの用語を、「犬のキャラクター」にたとえながら説明します。
クラス = 犬の「設計図」
「名前を持ち、あいさつができる犬」の設計図を考えてください。この設計図そのものがクラスです。設計図は1枚でも、そこから何匹でも犬を作れます。
インスタンス = 設計図から作った「本物の犬」
設計図をもとに実際に作った犬(「ポチ」「バディ」など)がインスタンスです。同じ設計図から作っても、それぞれ別々の名前を持つ独立した個体です。
属性 = その犬が持つ「データ」
「名前」や「年齢」など、その犬それぞれが持つデータが属性です。Pythonでは self.name や self.age のように self. を付けて書きます。属性はメソッドをまたいでずっと保存され続けます。
メソッド = その犬が「できること」
「あいさつをする」「走る」など、その犬ができる行動がメソッドです。関数とよく似ていますが、クラスの中に定義し、第1引数に必ず self を書く点が異なります。dog.greet() のように「インスタンス名.メソッド名()」の形で呼び出します。
self = 「自分自身」を指す変数
犬が「ぼくの名前はポチです」と言うとき、「ぼく」にあたるのが self です。メソッドの中で self.name と書くと、そのメソッドを呼び出した犬自身の名前を参照できます。どのインスタンスから呼ばれても、self はその呼び出し元を自動的に指します。
__init__ = 犬を作るときの「初期設定」
Dog("ポチ") と書いてインスタンスを作る瞬間に、自動で呼ばれる特別なメソッドです。「作るときに名前を渡して、その犬の属性として保存する」という初期設定を担います。名前の前後にアンダーバーが2つずつ(__init__)あるのが特徴で、この形は変えられません。
用語のイメージがつかめたら、実際のブロックを確認していきます。
ステップ1:Dogクラスのブロックをひとつひとつ読んでみよう
まず完成したブロック全体を確認してください。

ブロックは大きく2つに分かれています。上の紫のまとまりがクラスの定義(設計図を作る部分)で、下の緑〜紫の2行が実際にインスタンスを作って使う部分です。それぞれのブロックを見ていきます。
① クラスの入れ物

「クラス Dog を定義する」ブロックがクラス全体の入れ物です。Dog という名前の設計図をここで宣言し、このくぼみの中に __init__ やメソッドをまとめて入れます。
class Dog:② __init__ で初期設定する

「初期化(self, 引数: name ▼)」ブロックが __init__ メソッドです。Dog("ポチ") と書いてインスタンスを作る瞬間に自動で呼ばれ、引数 name(プルダウンで選ぶ変数)には渡した "ポチ" が入ります。
中の「self.name に name ▼ を入れる」ブロックが、受け取った name を属性として保存する処理です。self.name に入れることで、後から greet() を呼んだときにも自分の名前を参照できます。
def __init__(self, name):
self.name = name③ 属性の読み書き(self.〇〇)

self.name の self は「この犬自身」を指します。self.name は「この犬が持つ名前」のことです。self. から始まる変数が属性で、ポチなら "ポチ"、バディなら "バディ" とインスタンスごとに別々の値を持ちます。
④ メソッドで「できること」を定義する

「メソッド greet(引数なし)」ブロックが、犬の「あいさつをする」メソッドです。self.name を参照しているので、どのインスタンスから呼ばれても、その犬自身の名前が表示されます。
def greet(self):
print("こんにちは!ぼくの名前はね、" + self.name + "!")⑤ インスタンスを作って、メソッドを呼ぶ

「変数 dog ▼ を クラス Dog(引数: "ポチ")で作る にする」ブロックで、設計図からインスタンスを作ります。Dog("ポチ") と書いた瞬間、次の4つが順番に実行されます。
__init__が自動で呼ばれる- 引数
nameに"ポチ"が入る self.name = "ポチ"が実行され、このインスタンスの属性として保存される- できあがったインスタンスが変数
dogに代入される
続く「dog ▼ . greet(引数: )を呼ぶ」ブロックで、dog のメソッド greet を実行します。このとき self は自動で dog を指すので、self.name は "ポチ" になります。
ブロック全体が生成するコードと実行結果です。
class Dog:
def __init__(self, name):
self.name = name
def greet(self):
print("こんにちは!ぼくの名前はね、" + self.name + "!")
dog = Dog("ポチ")
dog.greet()こんにちは!ぼくの名前はね、ポチ!ステップ2:メソッドで属性を変えてみよう
メソッドは属性を読むだけでなく、書き換えることもできます。Counter(カウンター)クラスで試してみましょう。

__init__ で受け取った start を self.value として保存しています。tick() メソッドは呼ばれるたびに self.value を1ずつ増やす処理です。
ここで押さえておきたいのは、属性の変化はインスタンスに引き継がれる点です。tick() を呼んで増えた値が self.value に上書きされるので、次に tick() を呼んだときはその値からさらに1増えます。普通の変数と違い、属性はメソッドをまたいで持続します。
class Counter:
def __init__(self, start):
self.value = start
def tick(self):
self.value = self.value + 1
counter = Counter(0)
counter.tick()
counter.tick()
print(counter.value)2ステップ3:インスタンスはそれぞれ独立している
同じクラスから複数のインスタンスを作ると、それぞれが独立した属性を持ちます。設計図は1枚でも、そこから作ったインスタンスはお互いに干渉しません。

class Counter:
def __init__(self, start):
self.value = start
def tick(self):
self.value = self.value + 1
a = Counter(0)
b = Counter(100)
a.tick()
b.tick()
print(a.value)
print(b.value)a.tick() を呼んでも、変わるのは a.value だけです。b.value は100のままです。ポチが何かをしてもバディには関係ない——インスタンスはそれと同じです。
1
101コーディングモードで書いてみよう
慣れてきたら、属性を複数持たせたり、return で計算結果を返すメソッドを作ったりできます。Rectangle(長方形)クラスで面積を求める例です。
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
r = Rectangle(4, 3)
print(r.area())__init__ で2つの属性(self.width と self.height)を保存しているので、area() メソッドはその2つを掛け合わせるだけで面積 12 を返せます。
演習課題
課題16-1:別の名前で犬を作ろう
ステップ1の Dog クラスを使って、"バディ" という名前の犬を変数 buddy に作り、greet() を呼んでください。
詰まったときはこの順で考えてみてください。
- クラスの定義(設計図)は変える必要があるか?
→ 名前が違うだけで、設計図の構造は変わりません。Dogクラスの定義はそのまま使えます。 - インスタンスを作るブロックを選ぶ
→「変数 buddy ▼ を クラス Dog(引数: "バディ")で作る にする」ブロックを使います。引数に渡す文字列を"バディ"にしてください。 - メソッドを呼ぶブロックを選ぶ
→「buddy ▼ . greet(引数: )を呼ぶ」ブロックで呼び出します。インスタンスのプルダウンをbuddyに変えましょう。
▶ 模範解答と解説を見る
ブロックの組み合わせ例:

class Dog:
def __init__(self, name):
self.name = name
def greet(self):
print("こんにちは!ぼくの名前はね、" + self.name + "!")
buddy = Dog("バディ")
buddy.greet()解説: 変わったのは最後の2行だけです。Dog("バディ") と書くことで __init__ の name に "バディ" が入り、self.name に保存されます。buddy.greet() を呼んだとき self は buddy を指すので、self.name は "バディ" になります。同じクラス(設計図)から、何匹でも違う名前の犬インスタンスが作れます。
課題16-2:add3()メソッドを追加しよう
ステップ2の Counter クラスに、self.value を3増やすメソッド add3() を追加してください。Counter(10) でインスタンスを作り、add3() を呼んだ結果を表示してください。
詰まったときはこの順で考えてみてください。
- tick() メソッドの中身を確認する
→「self.value に self.value + 1 を入れる」です。属性を1増やして自分自身に上書きしています。 - add3() メソッドを tick() と同じ構造で追加する
→「メソッド add3(引数なし)」ブロックをtickブロックの次につなぎます。中身は「self.value に self.value + 3 を入れる」にします。 - インスタンスを作る
→「変数 c ▼ を クラス Counter(引数: 10)で作る にする」ブロックで、初期値10のカウンターを作ります。 - メソッドを呼んで確認する
→「c ▼ . add3(引数: )を呼ぶ」の後にc.valueを表示します。10+3=13が出れば成功です。
▶ 模範解答と解説を見る
ブロックの組み合わせ例:

class Counter:
def __init__(self, start):
self.value = start
def tick(self):
self.value = self.value + 1
def add3(self):
self.value = self.value + 3
c = Counter(10)
c.add3()
print(c.value)解説: add3() は tick() と同じ構造で、足す数を1から3に変えただけです。1つのクラスにメソッドはいくつでも追加でき、どのメソッドも属性 self.value を読み書きできます。Counter(10) で初期値10にして add3() を1回呼ぶと、self.value は 13 になります。
まとめ
- クラスはデータ(属性)と処理(メソッド)をひとまとめにした「設計図」です
- インスタンスは設計図から作った実体です。クラスは1つでも、インスタンスは何個でも作れます
- 属性(
self.〇〇)はインスタンスごとに独立したデータです。メソッドをまたいで保存され続けます - メソッドはクラスの中に定義する関数です。第1引数に必ず
selfを書き、インスタンス名.メソッド名()で呼び出します - self は「そのメソッドを呼び出したインスタンス自身」を指します
- __init__ はインスタンスを作るときに自動で呼ばれ、属性の初期値を設定する特別なメソッドです
次は、プログラムが予期しないエラーを起こしたとき、クラッシュさせずに対応する「例外処理」を学びます。→ Python × 入門 | #17 エラーをつかまえよう