Pythonのself変数は、クラスのインスタンスをインスタンスメソッドの中で使うためのものです。
インスタンス変数やメソッドにアクセスするためには、これをメソッドの第一引数として明示的に宣言する必要があります。
この変数はインスタンスメソッドでのみ使用されます。
ほとんどのオブジェクト指向プログラミング言語では、メソッドの引数として明示的に持つ必要がなく、メソッド内で現在のオブジェクトにアクセスすることができます。
例えば、Javaプログラムではthisキーワードを使ってカレントオブジェクトにアクセスすることができます。
しかし、Pythonでは、オブジェクトのインスタンスをself変数として明示的に宣言する必要があります。
この記事もチェック:Pythonでの変数の定義やスコープ、削除、globalキーワードを解説していく
Python selfは予約語(キーワード)なのか?
Pythonの変数selfは予約語ではありません(つまり、selfではなくthisとかの変数名でも良い)。
しかし、インスタンスを参照するために 変数名をselfとして使用するのがベストプラクティスであり、慣例です。
Pythonのself変数の例
例えば、以下のようなDogクラスが定義されているとします。
class Dog:
def __init__(self, breed):
self.breed = breed
def bark(self):
print(f'{self.breed} is barking.')
d = Dog('Labrador')
d.bark()
結果は、以下の通りになります。
ラブラドールが吠えています。
Labrador is barking.
関数には2つの変数が定義されていますが、Dogのインスタンスを生成する際には1つの引数しか与えません。
selfは新しく作成されたDogクラスのインスタンスに自動的に代入されます。
bark()メソッドの引数はselfのみで、このメソッドを呼び出したDogインスタンスにバインドされる。
そのため、bark()メソッドを呼び出す際には引数を渡さないようにしています。
もし関数内でインスタンス変数にアクセスする必要がある場合は、ドット演算子を使用することができます。
この記事もチェック:Pythonのexec関数の使い方|引数や変数の使い方を解説する
self変数を省略することはできる?
インスタンスメソッドがインスタンス変数にアクセスする必要がない場合はどうすればよいでしょうか。
結論から言うと、selfを省略することはできません。
簡単な例で調べてみましょう。
class Dog:
def bark():
print('Barking')
d = Dog()
d.bark()
上記の例だと以下の様なエラーが発生してしまいます。
Traceback (most recent call last):
File "Main.py", line 6, in
d.bark()
TypeError: bark() takes 0 positional arguments but 1 was given
エラー文にTypeError: bark() takes 0 positional arguments but 1 was given
とありますが、これはbarkメソッドの引数が1個あると期待したのに0個だったよ、と言うエラーです。
なので、selfは必須ですね。
この記事もチェック:Pythonのmapメソッドの使い方|ラムダ関数や引数が複数の場合の使い方も解説
クラスメソッドとスタティックメソッドで同じような変数があるか?
クラスメソッドでも同じような動作があります。
唯一違うのは、Classを参照する際の変数名として、cls
を使用する慣習があることです。
class Dog:
@classmethod
def walk(cls):
print('Dog is Walking')
Dog.walk()
しかし、スタティック・メソッドでは必要ありません。
なぜなら、スタティックメソッドは自己完結した関数であり、クラスの変数や関数に直接アクセスすることはできないからです。
それでは、self と cls 変数と引数のないスタティックメソッドの例を見てみましょう。
class Dog:
def __init__(self, breed):
self.breed = breed
@classmethod
def walk(cls):
print('Dog is Walking')
def bark(self):
print(f'{self.breed} is barking.')
@staticmethod
def add(x, y):
return x + y
Dog.walk()
d = Dog('Labrador')
d.bark()
print(Dog.add(10 , 20))
結果は以下の様になります。
Dog is Walking
Labrador is barking.
30
self変数が現在のインスタンスに束縛される
self変数によって、現在のインスタンスのプロパティにアクセスすることができます。
簡単な例として、Dogクラスの2つの異なるインスタンスを作成することで確認できます。
class Dog:
def __init__(self, b):
self.breed = b
def bark(self):
print(f'{self.breed} is Barking.')
d1 = Dog('Labrador')
d2 = Dog('Husky')
d1.bark()
d2.bark()
結果は以下の様になります。
Labrador is Barking.
Husky is Barking.