
ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第2回 「オブジェクトとクラス」学習メモ
はじめに
ノンプロ研で開催されている、「中級プログラミング講座【Pythonコース】」第1期 第2回の講座の内容と、学習したことをまとめていきます。
第2回のアジェンダは、「オブジェクトとクラス」です。
1.オブジェクト
オブジェクト

Pythonでは、すべてのデータを「オブジェクト」と言い、オブジェクトは、識別値、型、値を持っています。
オブジェクトを調べる関数としては、下記2つあります。
id(オブジェクト)…識別値を調べる
type(オブジェクト)…型を調べる
同一性判定演算子
オブジェクトを比較する場合、識別値が一致しているのか?もしくは格納する値が一致してくるのか?のどちらかを比較することとなります。
同一性…同じ識別値を持っているかを比較すること
等価性…格納する値が等しいかを比較すること

演習で確かめてみます。

実行結果確認してみます。

変数x, yに、10という値を設定したら、同じ識別値になることが確認できました。
異なる変数に数値を設定したのに、同じ識別値って?
これには理由あります。
現在の実装では、-5 から 256 までのすべての整数に対して整数オブジェクトの配列が保持されます。その範囲で int を作成すると、実際には既存のオブジェクトへの参照が返されます。
変数

値が格納されている場所を示すラベルとしています。
Pythonでは、値はそれぞれ独自の場所に保存されていて、変数はその値の場所を示すラベルである、と考えています。
変数を使用する場合、変数が指し示す場所に格納されている値を取り出して使用します。
イミュータブル

変更できないオブジェクトのことで、値の変化に従って、変数の参照先が変わります。
ミュータブル

変更可能なオブジェクトのことで、変数の参照先は変化しないが、値は変わります。

組み込み型一覧を見ると、ミュータブルなデータ型となるのは、リスト型、辞書型のみで、それ以外はすべてイミュータブルとなります。
下記のサイトにも組み込み型の分類がまとめてあり、大変参考になりました。
2.クラス

同じタイプのデータを持っていたり、複数データを作成したりする場合、クラスを定義すると便利です。
クラスとは、オブジェクトの型を定義する機能で、独自のオブジェクトを自作することができるようになります。

世界一簡単なクラスを作成していきます。

2行目のpass文とは、何も実行しないステートメント=文です。
pass文は、クラスや関数の定義のみを行う場合、if文の条件分岐時に何もしない場合、例外処理で何もしない場合などに使用します。
このクラス定義から、pass文をコメントアウトして実行してみます。
class Person:
# pass
結果を確認すると、クラスの定義を行った場合、インデントされたブロックが必要です、とエラーが発生します。

インスタンスの生成
class文を使って、クラスの定義を行った後、定義したクラスのオブジェクトを作っていきます。

クラスの定義を用いて、オブジェクトを作り、使用できる状態にするためには、インスタンスを生成するという手順を行います。

クラスとインスタンスの関係は、クラス=たい焼きの型、インスタンスは、クラス(たい焼きの型)からインスタンスを作成する(たい焼き)というようなイメージです。

インスタンスを生成する演習です。


実行結果を見ると、type関数で表示しているインスタンスの型は、__main__.Personとなっています。
この__main__はスコープの名前で、Personクラスが__main__スコープ上で定義されたことを表しています。
3.インスタンス変数
インストタンス変数

インスタンス変数とは、インスタンスごとに持っている変数で、個々のインスタンスで独立してデータを持っています。

Pythonでは、インスタンス生成後に、インスタンス変数をクラスの外部から追加することもできます。
また、インスタンス変数の削除は、del関数を使って行うことができます。

__init__メソッドはインスタンスの生成直後に呼び出され、インスタンスを初期化を行う特殊な関数です。
パラメータの1番目には、必ずselfを定義します。このselfは、生成されたインスタンスのことを指します。
コンストラクタ

コンストラクタとは、インスタンス生成時に実行される特殊な関数のことです。
C++、Javaなどのプログラミング言語でのコンストラクタは、インスタンスを生成する処理とインスタンスの初期化の処理を行うのが一般的です。
しかし、Pythonの __init__メソッドは、インスタンス生成後に呼び出されるという点が、厳密にコンストラクタの意味とは異なります。
そのため、__init__メソッドは、イニシャライザと呼ばれています。

インスタンス生成時に渡す引数が、クラス定義の__init__メソッドのパラメータとどのように関連しているか?を示しています。

selfは、インスタンス自身のことを示します。
self以外のキーワードを使用することもできますが、慣例としてPythonではselfを使用しています。
なぜ、明示的にPythonでselfを定義しなきゃいけないのか?を調べて、下記のサイトに行きつきました。
…理解できていないです💦
4.メソッドの定義
メソッドとは?

オブジェクトは、変数以外にも関数を持つことができます。それを、メソッドと呼びます。
メソッドの定義と呼び出し

メソッドは、def文を使って定義することができます。
def文を使って定義を行うのは、通常の関数と同じですが、違いは最初のパラメータがselfとなっている点です。

呼び出し時には、Python側でインスタンスのオブジェクトを渡してくれるため、第1引数のselfを引数として渡す必要はありません。
特殊メソッド
Pythonには、最初と最後がダブルアンダースコアで囲まれた特殊メソッドが存在します。Pythonが暗黙的に呼び出すメソッドとなります。

print関数実行時に実行される文字列を返します。
str関数実行時にも、この__str__メソッドが実行されます。
文字列表現の特殊メソッドには、他にも__repr__メソッドがあります。__repr__メソッドは、デバッグ時の情報を提供するために利用される特殊メソッドとなります。
他にも、数値演算、代入、比較を行うための特殊メソッド、まだまだあります。
おまけ
クラス変数
クラスが持つデータ属性には、インスタンス変数のほかに、クラス変数もあります。
クラス変数は、クラスに結びつけられた変数となります。
クラス変数は、クラスが独自に管理したいデータや、複数のインスタンスで共有したいデータを保存するために使用します。
class Orinigi:
currency = 'YEN'
def __init__(self, name, price, stock):
self.name = name
self.price = price
self.stock = stock
def get_price_with_currency(self):
return f'{self.price} {self.currency}'
クラス変数へのアクセスは、クラスの外からの場合、クラス名.クラス変数でアクセスできます。
print(Onigiri.currency)
クラス内からは、self.クラス変数でアクセスできます。
class Orinigi:
currency = 'YEN'
# <省略>
def get_price_with_currency(self):
return f'{self.price} {self.currency}'
なお、クラス内にインスタンス変数とクラス変数の名前が重複した場合、クラス内から参照する場合インスタンス変数が優先して参照されるようになります。
class Onigiri:
currency = 'Yen'
def __init__(self, name, price, stock):
"""コンストラクタ
Args:
name (str): 商品名(具)
price (int): 販売金額
stock (int): 在庫数
"""
self.name = name
self.price = price
self.stock = stock
self.currency = 'dollers'
def get_price_with_currency(self):
return f'{self.price} {self.currency}'
print(Onigiri.currency) # Yen
sake = Onigiri('sake', 130, 5)
print(Onigiri.currency) # Yen
print(sake.get_price_with_currency()) # 130 dollers
print(sake.currency) # dollers
講座ツイートまとめ
講座では、記憶定着化のため、アウトプットすることが推奨されています。受講された皆様方のツイートまとめは、下記よりご参照ください。
まとめ
今回は、ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第2回「オブジェクトとクラス」について、講座内容と学習のメモまとめました。
次回は、第3回「モジュール」です。
目次
1.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第1回 「関数と式」学習メモ
2.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第2回 「オブジェクトとクラス」学習メモ
3.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第3回 「モジュール」学習メモ
4.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第4回 「ファイル操作とAPI」学習メモ