Pythonはオブジェクト思考のプログラミング言語です。オブジェクトは、データと命令がセットになったもので、これまで扱ってきたものは全てオブジェクトとして扱えます。
では今まで誰も作ったことの無いオブジェクトを作るには、オブジェクトの内容を示すクラスを作る必要が有ります。
このクラスはプログラミングの中で部品のように使うことができ、より便利な処理を行うことができます。
ここではこのクラスについて学んでいきます。
クラスを定義する
クラスは、プログラムで利用するオブジェクトの設計図などと言われています。この設計図を書くことをクラスの定義と言います。
Pythonでクラスを定義する時の書き方は、こんな感じになります。
class クラス名():
pass
passは何も処理をしないコードを表す時にPythonではこう書きます。クラスが空だという意味になります。ここに関数を定義して処理を書いていきます。メソッドなどとも言います。インデントで字下げしているのは、Pythonの特徴ですね。
「クラス名()」のところは「クラス名」だけ書いて丸括弧を書かなくても構いません。また、「クラス名(object)」と定義して丸括弧に(object)と書くこともあります。コードのスタイルとして「クラス名(object)」と書くのが良いとされているという話もあります。
ココでは「クラス名()」という書き方を中心にやっていくつもりですが、違う書き方をしていても迷わないようにしましょう。
ちなみにクラス名は大文字で始めるというのが慣習になっているようです。(厳密には大文字で始まるキャメルケース)
具体的に簡単なコードを書いてみましょう。
class StudyPython():
def hello(self):
print("Hello! Python!")
StudyPythonというクラス名で定義しています。このクラスの中に、hello()関数を定義して「Hello! Python!」と出力するメソッドを作っています。
hello(self)と、丸括弧の中にselfの文字が入っています。クラスを定義する時には必ずこのselfを入れることになっています。自分自身を扱うというようなニュアンスですが、ここではとりあえずそう書くのがルールと覚えておきましょう。
このクラスを利用するには、変数に代入してオブジェクトを作ります。これをインスタンスを作るという言い方をします。
具体的にコードを書いてみましょう。
study = StudyPython()
study.hello()
ここではstudyという変数を用意してオブジェクトを作ります。この変数にクラス名()を代入するとインスタンスが作られます。丸括弧をつけるということに注意しましょう。
そうすると、このオブジェクトにドット(.)で繋げてクラス内の関数(メソッド)が使えることになります。
このコードを上に続けて実行してみましょう。(ファイル名はclass.pyとしてAtomで実行しています)
クラス内で定義したメソッドが実行されているのがわかります。
ここでは簡単な例でしたので、普通に関数を定義して出力するのと変わりませんが、この出力をどのような条件で行うかというような場合には、関数定義でいくよりも、クラスからオブジェクトを作って、それをその都度利用するというのが便利で効率的になります。
クラスの初期化 – __init__()
今度は、Pythonオブジェクトを初期化する特殊メソッドを含む形でクラスを定義していきましょう。初期化メソッドの__init__()を使います。
定義の書き方はこうなります。
/* Your code... */
class クラス名(): def __init__(self): pass
先ほどのコードに、__init__()を入れて次のように書き加えてみましょう。
class StudyPython():
def __init__(self):
print("プログラミングの勉強をしよう!")
def hello(self):
print("Hello! Python!")
study = StudyPython()
初期化メソッドを加えて、出力する処理を書いています。丸括弧()の中にselfを入れるのを忘れないようにしましょう。
変数に入れてオブジェクトを作った時点でコードを実行してみましょう。
このように、クラスをインスタンス化するだけで、この初期化メソッドが一番最初に実行されているのがわかります。
このようにクラスで最初に呼ばれるのが初期化メソッドの__init__()なので、この中でいろんな初期設定を設定していくということになります。
この初期化にnameを指定して値を保持するように名前を入れてみましょう。この時にselfを使います。次のようにコードを書き換えてみましょう。
class StudyPython():
def __init__(self, name):
self.name = name
print(self.name + "の勉強をしよう!")
def hello(self):
print("Hello! Python!")
study = StudyPython("Python")
__init__()のselfの後ろに、nameを指定します。selfは自分自身のnameを呼び出すという意味で、self.nameを指定し、そこにnameで指定した名前を代入するというコードになっています。このような変数をインスタンス変数と言います。そして、この名前を出力に使っています。
クラスをオブジェクトにする時に、名前を「Python」を指定してインスタンス化してみます。
実行してみます。
初期化メソッドが呼ばれて、指定した名前を使ってコードが実行されているのがわかります。このStudyPython(“Python”)のように値を入れなかったらエラーになります。これは関数の引数と同じように使えて、もし入れないならば、__init__(self, name = “Python”)というようにデフォルトの値を設定するような使い方もできます。
また、self.nameで保持した値は、他のメソッドの中でも使えます。次のように、コードを変えてみましょう。
class StudyPython():
def __init__(self, name):
self.name = name
print("{}の勉強をしよう!".format(self.name))
def hello(self):
print("Hello! {}!".format(self.name))
study = StudyPython("Python")
study.hello()
hello()メソッドの中で使うように、コードを書き換えています。変数をそのまま代入する形でも良かったのですが、format()を使って出力する形に変えています。
メソッドも呼び出して実行してみましょう。
self.nameで保持された値が、他のメソッドでも機能しているのがわかります。
このselfを使って、クラス内の別のメソッドを利用することもできます。
上のコードを次のようにもうひとつ関数の定義を加えて書き換えてみます。
class StudyPython():
def __init__(self, name):
self.name = name
def hello(self):
print("Hello! {}!".format(self.name))
self.learn()
def learn(self):
print("{}の勉強をしよう!".format(self.name))
study = StudyPython("Python")
study.hello()
初期化メソッドの中のprint文を削除して、初期化の定義だけにしています。
また、learn()関数の定義を追加しています。このメソッドのなかにprintで表示するコードを書いています。learn(self)と、selfを入れるのを忘れ無いようにしましょう。
そして、さらにhello()メソッドの中で、今定義したlearn()メソットを呼びだすコードを付け加えています。他のメソッドを呼び出す時にも、self.learn()のようにselfを使って利用するということにも注意しましょう。
このクラスからhello()だけを呼び出してみましょう。
実行するとこうなります。
hello()が追加したメソッドを呼び出して一緒に表示し、self.nameで保持した値も使えているのがわかります。
このようにして、クラスの定義と初期化の方法を学びました。ちょっとselfが出てくるところに最初のうちは慣れないかもしれませんが、しっかり理解していきましょう。
コンストラクタとデストラクタ
これまで書いたクラスのコードですが、最初に__init__()を使って初期化しました。これをコンストラクタと呼びます。オブジェクトを作るのに、一番はじめに呼ばれるものです。
それに対して、オブジェクトを終わりまで呼び出した後の最後に何かやりたい場合には、デストラクタというものを置くことができます。
デストラクタの書き方は次のようになります。
class クラス名():
def __init__(self): # コンストラクタ
pass
def method(self): # 例として定義しています。
pass
def __del__(self): # デストラクタ
pass
このように、クラスの中の最後に、__del__(self)を使って定義しています。
このデストラクタを使って、これまでのコードを書き換えてみます。
class StudyPython():
def __init__(self, name):
self.name = name
def hello(self):
print("Hello! {}!".format(self.name))
self.learn()
def learn(self):
print("{}の勉強をしよう!".format(self.name))
def __del__(self):
print("終了しました!")
study = StudyPython("Python")
study.hello()
最後に「終了しました!」と表示されるデストラクタを定義しました。
これを実行するとこうなります。
デストラクタが最後に実行されています。
では、このクラスから作ったメソッドを実行した後に、何か処理するコードが次の場合のようにあった場合はどうなるか見てみましょう。
class StudyPython():
def __init__(self, name):
self.name = name
def hello(self):
print("Hello! {}!".format(self.name))
self.learn()
def learn(self):
print("{}の勉強をしよう!".format(self.name))
def __del__(self):
print("終了しました!")
study = StudyPython("Python")
study.hello()
print("理解できてるのでしょうかね?")
最後に、print文で出力するコードを付け加えてみました。
実行してみましょう。
結果を見ると、メソッドを実行し、print文で加えた処理の最後まで実行した一番あとにデストラクタが呼び出されています。
これを、意図的に途中でデストラクタを呼び出すには、delを使ってオブジェクトを削除するコードを書きます。
class StudyPython():
def __init__(self, name):
self.name = name
def hello(self):
print("Hello! {}!".format(self.name))
self.learn()
def learn(self):
print("{}の勉強をしよう!".format(self.name))
def __del__(self):
print("終了しました!")
study = StudyPython("Python")
study.hello()
del study
print("理解できてるのでしょうかね?")
最後のprint文の前にdelキーワードを置き、オブジェクトのstudyを削除しているのがわかります。
これを実行するとこうなります。
オブジェクトが削除された時点でデストラクタが実行され、その後にprint文が出力されています。
先ほどの場合との動きの違いをよく確認しておきましょう。
まとめ
誰も作ったことの無いオブジェクトは、新しくクラスを作ってオブジェクトの内容を示す必要があります。クラスは部品の設計図のようなもので、設計図を作ることをクラスの定義と言います。
classキーワードに続けてクラス名を書き、丸括弧をつけてコロンを置いてクラスを定義していきます。インデントで字下げして処理するメソッドを書いていきます。
クラス内に定義するメソッドは、関数の引数にかならずselfを入れます。このselfのキーワードで値をクラス内で使う値を保持したり、メソッドを呼び出して使うことになります。
クラスをオブジェクトにするには、クラスを丸括弧をつけて呼び出して変数に代入します。このオブジェクトにドット(.)で続けてメソッドを呼び出すことができます。
クラスには初期化メソッドの__init__(self)を記述すると、最初にこの初期化メソッドが呼ばれることになるので、初期設定などをここに書き込むことになります。
初期化で始まる部分をコンストラクタと呼びます。オブジェクトが呼ばれて一番最後に何か処理をした時には__del__(self)を定義することができます。これをデストラクタと呼びます。
ここではselfで値を保持したり、メソッドを利用したりすることなど、これまででは見慣れないことがありますが、徐々に慣れていきましょう。