Pythonでは、クラスメソッドを定義する場合、第一引数は必ずselfを使わなければいけません。
しかし、なぜselfを使うのかという点について詳しく説明しているサイトはあまり多くないように感じます。
Pythonを使うのであれば、selfを使う理由はしっかりとおさえておきたいところ。
そこで今回は、クラスメソッドの引数にselfを使う理由についてみていきましょう。
前提とする知識
この記事を理解するためには、クラスの考え方について理解していることが必要です。
また、モジュールについても理解していることが好ましいです。
それぞれ、クラスという記事とモジュールという記事にまとめていますので、参考にしてみて下さい。
文字列に組み込まれている関数について考えてみる
まずは、upperメソッドを使って具体例でイメージをふくらませていきましょう。
upperメソッドは、文字列を大文字にするために使われます。
文字列型のオブジェクトにはupperメソッドがあらかじめ備わっていますので、文字列型のオブジェクトを作ればupperメソッドを使うことができます。
補足ここで?となる方は、クラスとオブジェクトという記事を読んでみるとよいかもしれません。
つまり、strクラスには、以下のようなメソッドが実装されているということです。
コードclass str():
def upper(object):
文字列を大文字にする処理
実際にstrクラスからupperメソッドを呼び出してみましょう。
コードを書いて検証してみましょう。
コードprint(str.upper('dog'))
アウトプットDOG
upperメソッドの引数をdogにした結果、DOGが出力されました。
ここで、upperメソッドの引数としてobjectを取っていることに注目しましょう。
upperメソッドは、引数を取る必要があります。
もうすこし具体的な表現としては、upperは文字列を大文字にする関数ですから、引数として大文字にする文字列を指定しなければいけません。
オブジェクトからメソッドを実行する
次に、文字列型のオブジェクトからupperメソッドを実行してみましょう。
コードanimal = 'dog'
print(animal.upper())
このコードを実行すると、結果はこのようになります。
アウトプットDOG
upperメソッドは引数を取らなければいけないにも関わらず、animal.upper()と引数を指定しなくても、DOGが出力されている点に注目しましょう。
普通であればこのコードはエラーになってしまうはずです(upperメソッドが引数を取っていないため)。しかし、実際はエラーにはなりません。
なぜエラーにならないのかというと、このコードは実際にはanimal.upper(animal)が実行されているからです。
しかし、animal.upper(animal)というのは、animalが続いていて少し見づらいですよね。
だから、Pythonではanimal.upper()といった形で、オブジェクトからメソッドにアクセスする場合には引数のオブジェクトを省略しても良いというルールにしたのです。
そういった意味では、クラスの中で定義されたメソッドの引数としてselfを取るのは当たり前のことなのです。
selfを引数として取らなかった場合を考える
更に理解を深めるために、selfを引数として取らなかった場合について考えてみましょう。
selfを引数として取らなかった場合というのは、クラスメソッドの引数としてオブジェクトを取らない場合です。
オブジェクトを引数に取らないメソッドが書かれたコードを書いてみます。
コードclass Calc():
def minus(a,b):
c = a - b
print(c)
return
クラスから直接クラスメソッドにアクセスすることで、メソッドを実行することができます。
具体的にコードを実行してみましょう。
コードCalc.minus(10,5)
アウトプット5
クラスから直接メソッドを呼び出して実行することができました。
一方、オブジェクトを作った場合はどうでしょうか?
コードa = Calc()
a.minus(10, 5)
アウトプットTypeError: minus() takes 2 positional arguments but 3 were given
エラーが出てしまいました。
これのエラーは、minus関数は位置引数を2つ取るような仕様である一方、位置引数が3つ与えられています。という意味です。
つまりminusメソッドは、オブジェクト、a、bという3つの引数を取らなければいけないということです。
これで、クラスメソッドの引数にselfが無い場合は、オブジェクトからメソッドを呼び出すととエラーになることが分かりました。
第一引数にselfを取る理由のまとめ
(1) オブジェクトからメソッドにアクセスしたとき、引数としてのオブジェクトが省略されているだけであり、引数としてオブジェクトを取ることが必要
selfを使う理由について学んだあとは
クラスに対する理解をさらに深めるために、継承について学んでいきましょう。