Lesson 7
クラス
目次
Lesson 7
Chapter 1
はじめに
Lesson 7
Chapter 2
スコープと名前空間
このチャプターでは、変数の有効範囲を示すスコープと、変数データ格納場所の関係について学んでいきます。 これらをしっかりと把握することで、予期せぬ変数の参照を防いだり、予め想定された変数の影響範囲によって適切な変数定義をすることが出来るようになります。
スコープの概要
スコープは、変数や関数が有効な範囲を指します。 Pythonのスコープは、変数や関数が定義された場所によって決まります。 種類としては、グローバルスコープ、ローカルスコープ、関数スコープ、クラススコープの4つに分類されます。
スコープ名 | 説明 |
---|---|
グローバルスコープ | モジュール全体に適用される |
ローカルスコープ | 関数やメソッド内に適用される |
関数スコープ | 関数内に適用される |
クラススコープ | クラス内に適用される |
名前空間の概要
名前空間は、変数や関数が格納される場所を指します。 Pythonの名前空間はスコープによって決まります。 スコープごとに異なる名前空間が存在し、各名前空間の中にグローバル変数やローカル変数が格納されます。つまり、複数のモジュールやプログラムで同じ名前の変数や関数を使用しても、それぞれが独立した空間に格納されているということになります。
実際にスコープと名前空間を確認してみよう
下記のコードでは、変数x
はグローバル変数として定義されています。また、関数test内では変数x
をローカル変数として再定義しています。
そのため、関数test内ではローカル変数x
を参照しprint
することになりますが、関数の外ではグローバル変数x
を参照しprint
しています。
sample.py
# グローバル変数
x = "global"
def test():
# ローカル変数
x = "local"
print(x)
test()
print(x)
出力結果
local
global
Pythonでのグローバル変数やローカル変数としての定義は、基本的には上下位置や、関数や制御構文内のインデントによって決まります。 このようにスコープによって名前空間も異なり、参照する変数も異なることが分かります。
グローバルキーワード
先程のプログラムで、関数内でグローバル変数を参照するためにはglobal
キーワードを使用する必要があります。
sample.py
x = "global"
def test():
global x
x = "local"
print(x)
test()
print(x)
出力結果
local
local
この例ではglobalキーワードを使用して、関数内でグローバル変数x
を参照しています。その結果、関数内でグローバル変数x
の値を変更し、関数外でもその変更が反映されることが分かります。
ここまでの説明を簡潔にまとめると、スコープと名前空間は以下のようになります。
- スコープ: 変数や関数が有効な範囲を示す。
- 名前空間: 変数や関数が格納される場所を示す。
スコープには、グローバルスコープ、ローカルスコープ、関数スコープ、クラススコープの4つがあり、それぞれに対応する名前空間が存在します。スコープによって、変数や関数が参照されることが決まります。
注意すべきことはグローバル変数とローカル変数の違いです。ローカル変数は、関数内で定義された変数で、関数外では参照できません。一方、グローバル変数は関数内外で参照することができます。もし関数内でグローバル変数を参照したい場合には、global
キーワードを使用します。

Lesson 7
Chapter 3
クラスの作成
クラスは、オブジェクト指向プログラミングにおいて、オブジェクトを定義するためのテンプレートのことを指します。クラスを使用することで、同じデータやメソッドを持った複数のオブジェクトを作成することができます。
クラスを定義するには、classキーワードを使用します。クラス名は自由に決めることができますが、一般的には各単語の頭を大文字で記述するパスカルケースという命名規則が使われます。
例えば、人間を表すクラスを作成する場合は、以下のようになります。
sample.py
class Person:
pass
このように、クラスを定義するときには、クラス名の後にコロンをつけ、インデントを使って中身を記述します。上記の例では、まだ中身が空のためpassを使用しています。
クラスの属性
クラスには、データ属性(プロパティ)とメソッドを定義することができます。データ属性は、クラスのインスタンスが持つデータを表します。メソッドは、クラスのインスタンスが実行できる処理を表します。
例えば、Personクラスには、名前や年齢といったデータ属性を定義し、自己紹介をするintroduce()というメソッドを定義することができます。
sample.py
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def introduce(self):
print("私の名前は" + self.name + "です。")
print(str(self.age) + "歳です。")
このように、クラスを定義することで、複数のインスタンスを作成し、それぞれに異なるデータ属性を持たせることができます。そして、これらのインスタンスは、クラスに定義されているメソッドを呼び出して、処理を実行することができます。
また、クラスには継承という機能があり、他のクラスを継承して新しいクラスを作成することができます。継承をすることで、既存のクラスの機能を継承し、新しい機能を追加することができます。
その他にも__init__
といった特殊なメソッドなど、わからない箇所が多くあると思いますが、これらに関しては後のチャプターで詳しく説明していきます。

Lesson 7
Chapter 4
インスタンスの生成
インスタンスはクラスから生成される具体的なオブジェクトのことで、クラスはオブジェクトの持つデータ(インスタンス変数)や処理(メソッド)を定義するための設計図です。
例えばCar
というクラスがあった場合、そのクラスからmy_car
というインスタンスを生成することができます。my_car
はCar
クラスが定義しているインスタンス変数やメソッドを持ち、実際に走ることができる車というオブジェクトになるイメージです。
sample.py
class Car:
def __init__(self):
self.color = "white"
def start_engine(self, message):
print(message + "エンジン始動!")
上記クラスのインスタンスを生成するには、以下のようにクラス名の後に()
をつけて呼び出します。
sample.py
my_car = Car()
これにより、Car
クラスからmy_car
というインスタンスを生成し、使用することができます。
同じクラスから複数のインスタンスを生成して、各インスタンスの変数やメソッドを呼び出したり、値を設定することもできます。
sample.py
my_car = Car()
your_car = Car()
my_car.color = "Red"
my_car.start_engine("私の車の")
your_car.color = "Blue"
your_car.start_engine("あなたの車の")
print(my_car.color)
print(your_car.color)
出力結果
私の車のエンジン始動!
あなたの車のエンジン始動!
Red
Blue
このようにインスタンスはクラスという設計図から生成されるため、同じクラスから生成された複数のインスタンスは属性や処理を持ちますが、それぞれ独自のデータを持つことができます。 複数のオブジェクトに共通する部分をクラスとして定義することは、オブジェクト指向プログラミングを行う上で重要な役割を担います。

Lesson 7
Chapter 5
メソッドオブジェクト
Pythonのクラスは、特定の型のオブジェクトを作成するためのテンプレートです。クラスにはインスタンス変数とメソッドが含まれており、インスタンス変数は、クラスから生成されるオブジェクト固有の情報を保持します。
一方、メソッドはクラスから生成されるオブジェクトに対して実行できる処理を定義します。
メソッドはクラス内部で定義される関数で、インスタンスに対して特定の処理を実行するために使用されます。クラス外部からは見えませんが、クラス内部では、インスタンス変数にアクセスしたり、他のメソッドを呼び出すために使用することができます。
クラス内でメソッドオブジェクトを定義するには、def
を使用します。
sample.py
class MyClass:
def my_method(self):
print("こんにちは")
メソッドはインスタンスを生成した後、インスタンスからメソッドを呼び出すことができます。インスタンス名.メソッド名
のように記述をします。
sample.py
my_object = MyClass()
my_object.my_method()
出力結果
こんにちは
また、インスタンス変数へのアクセスや他のメソッドを呼び出すためにself
を使用します。
sample.py
class MyClass:
def __init__(self):
self.count = 0
def my_method(self):
self.count += 1
print(self.count)
インスタンスを生成した後、インスタンスからメソッドを呼び出すことで、インスタンス変数にアクセスすることができます。
sample.py
my_object = MyClass()
my_object.my_method()
my_object.my_method()
my_object.my_method()
出力結果
1
2
3
このmy_method
メソッドでは、呼び出される度にインスタンス自身のインスタンス変数であるcount
変数に値を+1して、その内容を出力するプログラムとなっています。
第一引数のselfについて
ここまで見てきたメソッドの引数に必ず記述しているself
について説明してきます。
簡潔に言うとself
は「インスタンス自身を表すオブジェクト」を指します。
クラスメソッドの中で、インスタンス変数や別のメソッドを呼び出す場合に、self
を使用することで、インスタンス自身にアクセスすることができます。
インスタンスは、同じクラスから生成された複数のインスタンスが存在出来てしまうといった性質上、count
と定義されたインスタンス変数が「一体誰のcount
なのか?」といった事になります。
こういった事が起きないように、インスタンス変数が参照される際にインスタンスの情報をself
として一緒に渡してあげることで、「〇〇さんのcount
を参照したい」といった判断ができるようになります。
ここまでの説明で完璧に理解できなくても問題はありません。最初のうちは「メソッドを定義するときには第一引数にself
を書かなくてはならない」といった"おまじない"として覚えておきましょう。
__init__について
Pythonでは特殊な意味を持つ名前が付けられたメソッドが存在します。これらのメソッドは、特定の処理を行うために、Pythonが自動的に呼び出すことができます。
例えば、__init__
という名前のメソッドは、インスタンスの生成時に自動的に呼び出されます。これを「コンストラクタ」と呼び、インスタンスの初期化処理を記述するために使用します。
sample.py
class MyClass:
def __init__(self):
self.count = 0
上記のようにinit
メソッドを定義した場合、インスタンスを生成する時に自動的に呼び出され、インスタンス変数count
に0が代入されるようになります。
このようにPythonには他にも特殊な意味を持つ名前を持つメソッドが用意されているため、クラスを定義する際にはそれらを使うことでより簡単かつ効率的なプログラミングを行うことができます。

Lesson 7
Chapter 6
インスタンス変数
インスタンス変数は、インスタンスごとに保持される変数でクラスの中で定義されているメソッドからアクセスすることができます。インスタンス変数を定義するには、通常の変数と同じように定義します。 また、インスタンス変数はオブジェクトごとに独立して保持されるため、異なるオブジェクトでは、インスタンス変数の値が異なります。
以下のプログラムがインスタンス変数を使った例です。
sample.py
class MyClass:
def __init__(self):
self.count = 0
def count_up(self):
self.count += 1
# 2つの異なるインスタンスを生成
my_object = MyClass("わたし")
your_object = MyClass("あなた")
# インスタンス変数をカウントアップするメソッドを呼び出し、値を更新
my_object.count_up()
your_object.count_up()
your_object.count_up()
# インスタンス変数を参照して出力
print(my_object.count)
print(your_object.count)
出力結果
1
2
この例では、count_up()
メソッドが呼び出される度にインスタンス自身のインスタンス変数であるcount
変数に値を+1して、その内容を出力するプログラムとなっています。
__init__を使用したインスタンス変数の初期化例
これまでにあった例の中では主に、クラス定義の箇所でインスタンス変数の初期化も行っている方法でした。 ここでは少し応用的なインスタンス変数初期化の方法について説明します。具体的には、コンストラクタの引数を利用します。
sample.py
class MyClass:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
print("私は" + self.name + "です。")
print(str(self.age) + "歳です。")
ここではコンストラクタにname
とage
という2つの引数をセットしています。これをインスタンス化する際は以下のようになります。
sample.py
# インスタンスを生成
my_object = MyClass("パイソン", 33)
my_object.introduce()
出力結果
私はパイソンです。
33歳です。
インスタンス化のタイミングで、"パイソン"という文字列がname
変数に格納され、33という数値がage
変数に格納されるといった流れになっています。
注意点として、コンストラクタに引数をセットした場合、インスタンス化の際にクラスに必要な引数を渡さないとエラーとなりますので忘れずに設定しましょう。

Lesson 7
Chapter 7
クラスの継承と多重継承
Pythonではクラスを継承することができます。継承することで、既存のクラス(親クラス)の機能を引き継ぐことができ、自身独自の機能を追加することもできます。
以下は、継承の例です。
sample.py
class Person:
def __init__(self, name):
self.name = name
def say_hello(self):
print("こんにちは。私は" + self.name + "です。")
class Student(Person):
def __init__(self, name, school):
# 継承元のコンストラクタを呼び出す
super().__init__(name)
self.school = school
def say_hello(self):
# 継承元のsay_helloメソッドを呼び出す
super().say_hello()
print("私は" + self.school + "の生徒です。")
student = Student("太郎", "パイソン大学")
student.say_hello()
出力結果
こんにちは。私は太郎です。
私はパイソン大学の生徒です。
上記のコードでは、StudentクラスがPersonクラスを継承しています。Studentクラスは、Personクラスのsay_hello
メソッドを引き継ぐだけでなく、自身独自の機能としてschool
変数を持ちます。
次に、多重継承について説明します。多重継承とは、複数のクラスから継承を受けることを指します。以下は、多重継承の例です。
sample.py
class Person:
def __init__(self, name):
self.name = name
def say_hello(self):
print("こんにちは。私は" + self.name + "です。")
class Animal:
def __init__(self, species):
self.species = species
def say_species(self):
print("種族は" + self.species + "です。")
class Human(Person, Animal):
def __init__(self, name, species):
super().__init__(name)
self.species = species
human = Human("太郎", "人間")
human.say_hello()
human.say_species()
出力結果
こんにちは。私は太郎です。
種族は人間です。
この辺りから少し複雑になってきますが、ゆっくり順を追って見ていきましょう。まず、クラスの定義は無視して、実行されるプログラムについて見てみます。
sample.py
human = Human("太郎", "人間")
human.say_hello()
human.say_species()
ここでは最初に、Human
クラスをインスタンス化しています。そしてコンストラクタに対して"太郎"と"人間"の文字列を渡していることが確認できます。
では、この引数がどこで処理されるのかを解明するため、次にHuman
クラスに注目してみましょう。
sample.py
class Human(Person, Animal):
def __init__(self, name, species):
super().__init__(name)
self.species = species
Human
クラスにもコンストラクタはありますが、最初の行で記述されているsuper().__init__(name)
で親クラスのコンストラクタを呼び出しています。
しかし、親クラスはPerson
とAnimal
の2つが存在するため、一見どちらのコンストラクタを呼び出すのか疑問に思います。
実はこの問題は単純で、左側に記述しているコンストラクタが優先されます。つまり、Person
クラスのコンストラクタを実行しているということになります。
sample.py
class Person:
def __init__(self, name):
self.name = name
ここでまた1つ問題が生じます。それはAnimal
のコンストラクタが呼び出されないことによってspecies
が初期化されないといったことです。
しかし、こちらも既に解決策が施されています。Human
のコンストラクタに戻って確認すると、しっかりとspecies
を初期化している事が確認できます。
sample.py
class Human(Person, Animal):
def __init__(self, name, species):
super().__init__(name)
self.species = species # speciesの初期化
こうすることで、human.say_hello()
とhuman.say_species()
を正常に呼び出し、処理する事ができます。
最後に1つ補足ですが、多重継承による親クラス間のメソッド名重複にも同じことが言えます。
sample.py
class Japanese:
def say_hello(self):
print("こんにちは")
class English:
def say_hello(self):
print("Hello")
class Human(Japanese, English):
pass
human = Human()
human.say_hello()
出力結果
こんにちは
このように、継承の箇所で左側に記述した親クラスのメソッドが優先される事が確認できます。 念の為、継承の順番を逆にすることで結果も変わることを確認してみましょう。
sample.py
class Japanese:
def say_hello(self):
print("こんにちは")
class English:
def say_hello(self):
print("Hello")
# Englishを優先して継承
class Human(English, Japanese):
pass
human = Human()
human.say_hello()
出力結果
Hello
このように継承を使うことで、既存のクラスの機能を引き継ぎながら新しいクラスを作成することができ、コードの繰り返しを避けることを意味するDRY(Don't Repeat Yourself)原則に従って、効率的なプログラミングをすることができるようになります。

Lesson 7
Chapter 8
プライベート変数
Pythonにおいてプライベート変数とは、クラスの外部からアクセスすることを想定していない変数のことを指します。プライベート変数は、クラス内部でのみ使用されることを想定しています。
以下は、プライベート変数の例です。
sample.py
class Person:
def __init__(self, name):
self.__name = name # プライベート変数
def say_hello(self):
print("私は" + self.__name + "です")
person = Person("パイソン")
print(person._Person__name)
出力結果
パイソン
プライベート変数の定義の仕方はシンプルで、インスタンス変数名の頭に__
(アンダースコアを2つ)付けることでプライベート変数として定義できます。
外部からプライベート変数を参照する
一方で、外部からのプライベート変数の参照の仕方には大きく違いがあります。
sample.py
print(person._Person__name)
この部分に注目すると、インスタンス名._クラス名プライベート変数名
という特殊な記述をしています。そしてもう1つ疑問な点として、クラスの外部からプライベート変数であるはずの__name
変数を参照できてしまっているという点です。
実は、Pythonのプライベート変数は完全なプライベートではなく、あくまで外部から参照する必要のない変数というルールレベルの定義になります。プライベート変数は単純に_クラス名プライベート変数名
といった形の変数名に置き換わるだけの物という風に解釈しても問題はありません。
では、ここまでの説明でプライベート変数の定義の仕方と外部からの参照の仕方について学びました。最後に、メソッド内でのプライベート変数の参照方法について説明していきます。
内部(メソッド)からプライベート変数を参照する
以下のコードは、同クラス内のプライベート変数を参照しているsay_hello
メソッドを呼び出すプログラムです。
sample.py
class Person:
def __init__(self, name):
self.__name = name # プライベート変数
def say_hello(self):
print("私は" + self.__name + "です")
person = Person("パイソン")
person.say_hello()
出力結果
私はパイソンです
このように、self.__name
とするだけで呼び出すことが出来ます。また、以下の記述方法でも同じ結果となります。
sample.py
class Person:
def __init__(self, name):
self.__name = name # プライベート変数
def say_hello(self):
# self._Person__nameに変更
print("私は" + self._Person__name + "です")
person = Person("パイソン")
person.say_hello()
出力結果
私はパイソンです
この例では、外部からプライベート変数を呼び出す際と似た形になっており、この記述方法でも同様に呼び出すことが出来ます。
以上がクラスに関する基礎的な記述方法になります。これらの内容を身につけることでプログラムがより簡潔かつ保守性が高くなりますので、オブジェクト指向をマスターしてみましょう。
