オブジェクトの作成(Using Databases with Python: Week 1)
ミシガン大学がCoursera上で開講しているPython for Everybody Specializationの第4コースを受講した記録です。さすがに難しくなってきたのでほぼ自分用のメモとして作っています。
このコースでは、オブジェクト指向プログラミングの基礎を詰め込んだ後、データベースの仕組みからSQLを用いたデータベースの操作、さらにはビジュアライゼーションまでをカバーします。
1.イントロダクション
<テキストの範囲>
Chapter 14: Object-Oriented Programming
まず、最初の動画ではじめてSQLがStructured Query Languageの略だということを知りました。(恥ずかしい)
とにかくこの講義ではオブジェクト指向プログラミングをPythonで実際に始める前に、コンセプトを理解することが求められます。
プログラムそのものの話に戻ると、プログラムは入力されたデータを何らかの形で処理し、その結果を出力するものです。実際にプログラムを使うユーザーは、処理の中身を知る必要はありません。
オブジェクトは、それ自身にコードとデータを持つ構造を持ったもの、と言うことができます。オブジェクトはそれ自身、何を処理するかがあらかじめ決められていますから、あるデータをオブジェクトに渡してしまえば特定の処理を勝手に行ってくれるというわけです。
オブジェクト指向プログラミングで用いられる用語は以下のとおりです。
・クラス……いわゆるテンプレート。クッキーの型みたいなもの。
・メソッド(メッセージ)……クラスに含まれる命令、処理
・フィールド(アトリビュート)……クラスに含まれるデータ
・オブジェクト(インスタンス)……クラスによって作られたもの。クッキーそのもの。
※Webで用いられるcookieではない
これまでに行ってきたPythonプログラミングにおいても、いくつかのオブジェクト(っぽいコード)があります。
a = 'Hello World!!'
x = list()
y = dict()
上で定義されたディクショナリyも、リストxも、特定のメソッドを持ちます。例えば以下のdirを用いると、リストxに含まれるメソッド等を確認できます。
print(dir(x))
リファレンスは以下をご参照ください。
2.オブジェクトを定義する
クラスを定義するには、classを用います。以下のコードでは、clsというクラスを定義し、クラスの中にはkというフィールドとmetというメソッドを持つものとしています。インデントされた部分がクッキーの”型”になるわけです。
class cls:
k = 0
def met(self):
self.k = self.k + 2
print('So far...', self.k)
val = cls() #...(1)
val.met() #...(2)
val.met()
(1)にて、valというクッキーを作ります。valというクッキーが作られたので、(2)にてmetというメソッドを実行しています。selfというのは、ここでは「valクッキーそのもの」を参照するものと理解しましょう。
クラスの中に何が定義されているのかは、dirで確認できます。
3.オブジェクトの作成と破棄を理解する
次に、クラスの作成と破棄プロセスを見ていきましょう。クラスが作成された時をコンストラクタ、クラスが破棄された時をデストラクタといいます。以下のプログラムを見てみましょう。
class cls:
k = 0
def __init__(self):
print('Constructed!!')
def met(self):
self.k = self.k + 2
print('So far...', self.k)
def __del__(self):
print('Destructed!!')
val = cls() #...(1)
val.met()
val.met()
val = 35 #...(2)
print(val)
(1)では、valというオブジェクトを作成したのでConstructed!!という文字が現れると思います。(2)で単に数値を代入していますが、Pythonでは型の異なる変数を代入すると、勝手に変数の型を変えてしまいますのでクラスが自動的に破棄されることになります。
x=43
x='xyz'
このようにプログラムするのと同じですね。
4.異なるオブジェクトを作成する
次に、異なるオブジェクトを作成してみましょう。以下では、(1)でAkiraという名前を持つval1オブジェクトが作成され、(2)でMayumiという名前を持つval2オブジェクトが作成されています。
class cls:
k = 0
name = ""
def __init__(self, onamae):
self.name = onamae
print(self.name, ': Constructed!!')
def met(self):
self.k = self.k + 1
print(self.name, ': So far...', self.k)
val1 = cls("Akira") #...(1)
val1.met()
val2 = cls("Mayumi") #...(2)
val2.met()
val1.met()
これを実行すると、以下のようなアウトプットになります。
Akira : Constructed!!
Akira : So far... 1
Mayumi : Constructed!!
Mayumi : So far... 1
Akira : So far... 2
最後はval1を呼び出しているので、Akiraという名前を持つオブジェクトが参照され、変数kが1足されることになります。
5.インヘリタンスを理解する
あるクラスで定義した性質を持ちつつ、他の性質を定義することができます。Aというクラスで定義した性質はそのままに、追加的にBというクラスを作るイメージです。教授は拡張(extend)という表現を用いています。
具体的にプログラムを見ていきましょう。
class A:
x = 0
name = ""
def __init__(self, onamae):
self.name = onamae
print(self.name, ': Constructed!!')
def method1(self):
self.x = self.x + 1
print(self.name, ': So far...', self.x)
class B(A): #...[1]
y = 0
def method2(self):
self.y = self.y + 5
self.method1() #...[2]
print(self.name, ': Then...', self.y)
val1 = A("Akira")
val1.method1()
val2 = B("Mayumi")
val2.method1() #...[3]
val2.method2() #...[4]
このプログラムでは、Akiraという名前を持つval1オブジェクトはAしか参照できませんが、Mayumiという名前を持つval2オブジェクトはAもBも参照することができます。
[1]というようにクラスを定義することで、クラスBはAの性質も持ち合わせる(Aの機能に追加してBの機能を持つ)ことができるようになっています。そのため、[2]のように、Bというクラスの中でAにある命令を行うこともできます。したがって、実行結果は以下のような形になります。
Akira : Constructed!!
Akira : So far... 1
Mayumi : Constructed!!
Mayumi : So far... 1
Mayumi : So far... 2
Mayumi : Then... 5
[3]の命令では、クラスAにある命令を実行しています。一方で、[4]の命令では、クラスBにある命令を実行していますので、クラスBを実行中にクラスAの命令を実行しています。そのため、Mayumiという名前を持つval2オブジェクトに持っている変数kを1足して、2を出力していますね。
このようにして、オブジェクトを単体で動かすことも、拡張機能を持たせることもできるということを今回の講義で学びました。
次回、いよいよデータベースに入っていきます。
この記事が気に入ったらサポートをしてみませんか?