スポンサードリンク
よくネットを見ているとPythonのクラスやらインスタンスやらメソッドやらの記事を見かけますが、どれも初心者の自分には敷居が高すぎます。まず、文章が長いし、言葉も専門用語の説明なのでむずい。
今回はこのドキュメントを使って自分なりに理解したことをpython初心者の方のために書いていこうと思います。
クラスがどうとかインスタンスがどうとかの前に…
習うより慣れろの概念で、まず下のコードを見てください。
1 2 3 4 5 6 7 8 9 10 11 |
class Userinfo: def __init__(self,name, birth,address): print("iitialize instance") self.name = name self.birth = birth self.address = address taro = Userinfo("taro",1986,"tokyo") print(taro.name) print(taro.birth) print(taro.address) |
classで何かを宣言していて、その中に詳細を記述しています。ここでは関数を書いています。
今は中身がどうとかはほっときます。
そしてclassの外で今度は、
「太郎、君の情報は Useinfoの東京、1986、タロウだね。」と宣言されています。
そして最後に
「太郎、名前を書いてくれ」「太郎、生まれた年代を書いてくれ」「太郎、住所を書いてくれ」と言われいます(print文)
以上から言えるのは、
- classの中身を使う(太郎の詳細を知る)ために、そのツール(Userinfoというclass)を宣言しなければいけないということ.
- 誰に対してそれを使うのか(ここではtaro)を書かなければいけないということ.
もう少し理解するために別の例を。以下はこのドキュメントの演習4の答えです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#!/usr/bin/env python # -*- coding: utf-8 -*- class Score: def __init__(self): self.name = '' self.math = 0 self.english = 0 self.japanese = 0 taro = Score() taro.name = 'taro' taro.math = 60 taro.english = 70 taro.japanese = 80 jiro = Score() jiro.name = 'jiro' jiro.math = 80 jiro.english = 70 jiro.japanese = 90 saburo = Score() saburo.name = 'saburo' saburo.math = 50 saburo.english = 30 saburo.japanese = 60 math_max_student = taro for student in [taro, jiro, saburo]: if (math_max_student.math < student.math): math_max_student = student print(math_max_student.name) |
上で述べたことから推測すると、今度は使いたい人が三人(taro,jiro,saburo)いるようです。しかも今回使うツールはScore(クラス)というもの。
なので、コードにちゃんと
1 2 3 |
taro = Score() jiro = Score() saburo = Score() |
が、場所は離れていますが宣言されています。
最初の例では、ツール(クラス)を宣言する際に、ツールを使って何の情報がいるのかも()の中で引数として宣言しています。こちらの方が行数が少なくてすむのですが、今回(2つ目の例)は違う書き方をしています。
要するに、jiroの名前、jiroの数学、jiroの英語、jiroの国語と別々に宣言しています。
コードで表すと、今は
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
taro = Score() taro.name = 'taro' taro.math = 60 taro.english = 70 taro.japanese = 80 jiro = Score() jiro.name = 'jiro' jiro.math = 80 jiro.english = 70 jiro.japanese = 90 saburo = Score() saburo.name = 'saburo' saburo.math = 50 saburo.english = 30 saburo.japanese = 60 |
となっている部分を
1 2 3 |
taro = Score("taro",60,70,80) jiro = Score("jiro",80,70,90) saburo = Score("saburo",50,30,60) |
と直接ツール(クラス)を宣言する時に、値を代入して何の情報を得るか指定することができるわけです。
これを可能にするため、最初のdef __init__(self)の部分に引数を追加し
1 2 3 4 5 |
def __init__(self,name, math, english, japanese): self.name = name self.math = math self.english = english self.japanese = japanese |
と書き直します。
コード全体を書き換えると、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Score: def __init__(self,name, math, english, japanese): self.name = name self.math = math self.english = english self.japanese = japanese taro = Score("taro",60,70,80) jiro = Score("jiro",80,70,90) saburo = Score("saburo",50,30,60) math_max_student = taro for student in [taro, jiro, saburo]: if (math_max_student.math < student.math): math_max_student = student print(math_max_student.name) |
def __init__の部分で、self~にnameだのmathだの,englishだの保持しておこうってことです。
そしてこれがまさしくインスタンス化です。今の自分の知識ではこれの恩恵が理解できないですが、二つ目の例のように冗長なコードが短くなっています。言い換えると、何かわからんがセットに(コンパクトに)なっている。
これが僕が参考にしているドキュメントの
「構造体とクラスの違いについて取り扱います。簡単に言ってしまうと、構造体は内部にデータだけを持ちますが、クラスはデータに加えて処理も内部に持っているというのが両者の違いです。」
と書かれている部分の「クラスはデータに加えて処理も内部に持っている」と言うことなのでしょう。
スポンサードリンク
お相手はあくまでpcです。
しかしここで問題が生じる。
なんで
1 2 3 |
taro = Score("taro",60,70,80) jiro = Score("jiro",80,70,90) saburo = Score("saburo",50,30,60) |
の部分を
1 2 3 |
taro = Score(60,70,80) jiro = Score(80,70,90) saburo = Score(50,30,60) |
これじゃいかんのよと。だってすでに名前わかってんじゃん(誰の情報欲しいかわかってんじゃん)って。確かにだからこそツール(クラス)を宣言する際に、taroとかjiroとかsanburoとか使ってんじゃんってなります。
それはtaroさんやjiroさんやsaburoさんの情報にもちろん本人の名前も含まれるからです。なのでそれをちゃんと明記してあげる必要があるわけです。
こちらは自明でもプログラムを処理するpcはtaroさんの名前が本当に”taro”かどうかわかりません。なのでそれが自明な我々からしたらアホみたいなことしてるように見えますが、相手はpcなのでしっかり教えてあげましょう。
次回はインスタンス化の利便性、使い所についてもう少し深めて理解してみたいと思います。
どうでしょうか。インスタンス、クラスとかの理解に助けになれば幸いです。あと個人の理解を記したものなので、書き方、異なる解釈をしていると感じた方はコメントをいただけると大変ありがたいです。
是非とも一緒に理解を深めましょう。