目次記事
前の記事
クラス、オブジェクト
クラスとは、オブジェクトを生成するための設計図です。オブジェクトとは実際にPCのメモリ上に記憶される実態です。
下記はPythonのドキュメントからの引用です。
クラスはデータと機能を組み合わせる方法を提供します。 新規にクラスを作成することで、新しいオブジェクトの 型 を作成し、その型を持つ新しい インスタンス が作れます。 クラスのそれぞれのインスタンスは自身の状態を保持する属性を持てます。 クラスのインスタンスは、その状態を変更するための (そのクラスが定義する) メソッドも持てます。
詳しくはこちら。
ま、ややこしい概念を演繹的に理解するなんて無理です。実例とかから帰納的に理解していきましょ。
オブジェクト指向プログラミング(OOP)
現実にあるあらゆる概念・物質を「属性(データ)と動作(メソッド)」で表現したい!
というのがオブジェクト指向プログラミング(Object Oriented Programming, OOP) の考え方です。メソッドはクラスの中の関数くらいに思っておいてください。
例えば「生き物」という概念を「属性(データ)と動作(メソッド)」で表現するなら、
- 「生き物」の属性 ... 質量がある。名前がある。年齢がある。
- 「生き物」の動作 ... 動く。年を取る。
みたいな感じです。これを「生き物クラス (class LivingThings)」として Python のプログラムで表現すると、
>>> class LivingThings(): # 生き物(LivingThings)クラスの作成
... # 名前(name)、年齢(age)、質量(mass)が生き物クラスが持つ属性(データ)
... def __init__(self, name, age, mass):
... self.name = name
... self.age = age
... self.mass = mass
...
... def move(self): # 生き物は動く
... print(f"{self.name}が動いた")
...
... def grow(self): # 生き物は年を取る
... print(f"{self.name}の年齢は{self.age} から"
... f"{self.age + 1} になった。\n"
... f"質量は {self.mass +1} になった。")
... self.age += 1
... self.mass += 1
これが 「生き物」というオブジェクトを生成するためのクラス(設計図) です。
ついでに使う様子も見ておきます。
>>> foo = LivingThings("イッヌ", 3, 10) # 生き物インスタンス(生き物オブジェクト)を生成
>>> foo.move() # 生き物インスタンスのメソッド move を呼び出し(コール)
イッヌが動いた
>>> foo.grow() # 生き物インスタンスのメソッド grow を呼び出し(コール)
イッヌの年齢は3 から4 になった。
質量は 11 になった
少し用語を整理しておきます。この時点ですべて覚える必要なんてありませんがね
-
インスタンス化、インスタンス生成
クラスから作成されたオブジェクトをインスタンスと言います。クラスをもとにオブジェクトを生成することをインスタンス化と言います。
オブジェクトとインスタンスって用語がごっちゃになりそうですね。
オブジェクトはとんでもなく広い概念で「メモリ上に保管された実態のすべて」くらいに考えてください。例えば、class ~~~
というクラス定義がある時点で、(たとえそのクラスのインスタンスを生成しなくても)クラスオブジェクトというオブジェクトが生成されます。
ほかにも def ~~~
で関数定義を書くと、関数を呼び出さなくても関数オブジェクトというオブジェクトが生成されます。
対して、インスタンスという用語は「クラスから作成した実体」のみを指します。インスタンスもオブジェクトの一種ですが、より小さな概念です。
- インスタンス変数
そのインスタンス固有の情報(属性)を格納する変数をインスタンス変数(または動的フィールド)と言います。今回のインスタンス変数は「名前(name)、年齢(age)、質量(mass)」の3つです。
インスタンス変数は、そのインスタンス自身が所有すべきデータです。
「生き物」クラスをインスタンス化したとき、犬や猫、虫や人や細菌など様々なインスタンスが作られます。これらのインスタンスそれぞれで異なる可能性があるデータがインスタンス変数です。
インスタンス変数は次で説明する コンストラクタ の中で宣言します。
- コンストラクタ
インスタンスを生成する際に一度だけ呼ばれる初期化処理がコンストラクタです。
コンストラクタの中で宣言されたすべての変数はインスタンス変数となります。
コンストラクタはメソッド名が __init__()
のモノです。メソッドには引数を入れることが可能です。クラス内で self
と書かれた変数はそのインスタンス自身を指します。self の実引数はインスタンス生成時には指定しません。
改めて、今回作成したコンストラクタの中身を確認します。
... def __init__(self, name, age, mass):
... self.name = name
... self.age = age
... self.mass = mass
このコンストラクタの定義で、「インスタンス生成した際に指定した引数 name
、age
、mass
の値を、生成されたインスタンス自身の属性(self.name
、self.age
、self.mass
)に代入する。」という意味になります。
下記のように生き物クラスをインスタンス化した場合、生成されたインスタンスの名前属性(self.name
)には "イッヌ"
が入ります。年齢、質量も同様です。
>>> foo = LivingThings("イッヌ", 3, 10)
- メソッド
クラスの中で定義された関数をメソッドと言います。メソッドはそのクラスのインスタンスの動作・ふるまいを記述する箇所です。ここでも引数の self
で自身のオブジェクトを指します。呼び出すには インスタンス変数名.メソッド名
と書きます。
>>> foo = LivingThings("イッヌ", 3, 10) # 生き物インスタンス(生き物オブジェクト)を生成
>>> foo.move() # 生き物インスタンスのメソッド move を呼び出し(コール)
イッヌが動いた
>>> foo.grow() # 生き物インスタンスのメソッド grow を呼び出し(コール)
イッヌの年齢は3 から4 になった。
質量は 11 になった
IDEで開発
これから VS Code を使って開発を行います。環境設定についてはどこか別の記事を参照してください。
本記事ではデスクトップに「python_practice」というフォルダを作成して、その中でいろいろ練習用の .py ファイルを作成していきます。
一度簡単なプログラムを作ってみて実行すのがいいかなって思うので、testclass.py というファイルを作成して下記のプログラムを書いて実行してみます。
class LivingThings():
def __init__(self, name, age, mass):
self.name = name
self.age = age
self.mass = mass
def move(self):
print(f"{self.name}が動いた")
def grow(self):
print(f"{self.name}の年齢は{self.age} から"
f"{self.age + 1} になった。\n"
f"質量は {self.mass +1} になった。")
self.age += 1
self.mass += 1
foo = LivingThings("イッヌ", 3, 10)
foo.move()
実行した結果、コンソールに次の文字が出ていれば成功です。
イッヌが動いた
次の章では、クラスの継承や、ポリモーフィズムといった概念を理解していきます。