はじめに
Pythonのクラスを学んだときに持ちそうな様々な疑問とそれに対する回答をまとめてみました。間違い等ございましたら、コメントください。
Q1: self
とは何ぞや
Pythonではインスタンスのメソッドを呼び出したとき、そのインスタンス自身が第一引数に渡されることになっています。これをself
という変数で受け取っているというだけのことなのです。self
はただの名前だったのです。ちゃんちゃん
「ちょまてよ、メソッドを使うときわざわざ第一引数にインスタンスなんて渡したことないぞ」という疑問を持つ人もいるでしょう。instance.function()
のような場合、第1引数にインスタンスが渡されることになっています。Pythonで決められているのは第1引数にインスタンスが入るということだけなので、別にself
以外の名前を使ってもいいですよ。Pythonでは慣例的にself
を使うようにしているようです。また、class.function()
とした場合、引数は自動的に渡されません。この辺について拙著で解説しています。
Q2: __init__()
とは何ぞや
変な下棒がついてるからって敬遠しないで、意外と簡単!この下棒はアンダースコア、アンダーバーと言われます。前後に2つづつ付いているのは、Pythonにとってこの関数が特別な機能を持つことを表しています。特別な機能を具体的に説明すると、クラスがインスタンス化されたときに自動的に実行されるという機能です。その際、インスタンス化するときに括弧の中に書いた引数が、__init__()
に引数として渡されます。ふつうはインスタンス変数の定義をするために使われます。
一般的にこのような機能を持つメソッドはコンストラクタと呼ばれます。
名前につくアンダースコアについてさらに知りたい方はこちらの拙著もどうぞ
Q3: クラス変数とインスタンス変数の違い
単純に、「クラスの変数に代入するか、インスタンスの変数に代入するか」の違いです。instance.function()
とするか、class.function()
の違いです。
class Person:
__init__(name. age):
self.name = name
self.age = age
上のコードのように、たいてい__init()__
の中でインスタンス変数を定義しますが、インスタンスが入っているself
のname
とage
に代入しているので、これはインスタンス変数を定義しています。もちろん、クラスからインスタンスを作った後で、instance.function()
としても、インスタンス変数を定義しています。ちょっと回りくどい書き方ですが、下のコードのようにして__init__()
内でクラス変数を定義することもできます。コンパクトな書き方をこちらの拙著で解説しています。
class person:
def __init__(self, class_, name):
class_.name = name
ken = person(person, "hoge")
print(person.name)
結果
hoge
クラス直下に書いた変数はそもそもクラスに所属しているのでクラス変数ですね。
Q4: 継承ってどうやって使うんや?
クラス定義は最も単純に書くと
class Food:
となりますが、
class Food(item):
とすることで、クラスの親を指定することができます。
継承した場合、クラス内に存在するメソッド、クラス変数は引き継がれます。もちろん__init__()
も引き継がれます。また、メソッドの機能を少し変えたい場合は、同じ名前のメソッドを定義することで上書きすることができます。もちろん新たなメソッドを定義することで、メソッドを追加することもできます。
__init__()
も上書きすることで新たにインスタンス変数を決めることができますが、インスタンス変数の追加のみを行いたい場合は、super().__init__()
を使うことで重複するコードを書かずに済みます。
Q5: super()
って何ぞや
super()
の引数にクラスを与えると、親クラスが返ってきます。クラスの中で使用すると引数を与えなくても自動的にそのクラスが与えられます。よく使われるのは、親クラスのコンストラクタを呼び出すときです。super().__init__(name,price)
と書くのですが、selfを書かなくていいのは、通常のメソッドがselfを書かないのと同じと考えていいと思います。
Q6: .pyファイルってどうやって分ける?(超個人的見解)
基本的には1.pyファイル1クラスでやる。その他によく使う処理をまとめたファイルを一つ作ってもいい。それらをコントロールするファイルも必要になる。