selfについて

3.3 selfについて

先ほどから何度も登場しているselfについて再度、説明していきたいと思います。

3.3.1 selfとは

先ほど繰り返しになりますが、selfは「オブジェクト(インスタンス)自身」を意味するものです。一般的にはコンストラクタの第一引数としてselfを指定し、インスタンス変数を宣言する際に、「self.インスタンス変数」という形式で使用します。

書式:selfの主な使用方法

また便宜上、selfと表現していますが、selfはあくまで仮引数に過ぎません。コンストラクタの第一引数にはself以外を指定することも可能で、コンストラクタの第一引数こそが、インスタンスそのものを表しているのです。
しかし開発現場の多くでは、コンストラクタを定義する際、第一引数にselfを指定されます。selfの使用はPythonの暗黙のルールとなっているといえるので、コンストラクタの第一引数にはselfを使用するようにしましょう。

3.3.2 メソッド間におけるインスタンス変数(self)の共有

インスタンス変数は同クラス内の他のメソッドで共有することもできます。その際に共有先のメソッドでは第一引数を指定する必要があり、第一引数にselfを指定するのが一般的ですので、selfを指定してください。
以下で他のメソッドにインスタンス変数を共有する際の一般的な書式を紹介します。

書式:インスタンス変数をメソッド間で共有する際の一般的な書式

上記の通り、他のメソッドでインスタンス変数を使用する場合にも、「self(第一引数).(ピリオド)インスタンス変数」と記載します。
書式だけだとわかりづらいかと思いますので、続いて他のメソッドでインスタンス変数を共有した場合のプログラムを確認していきましょう。

3.3.3 メソッド間でインスタンス変数を共有したプログラム

上記の書式の内容を踏まえ、クラス内で定義されたメソッド内で、同じクラス内で定義されたインスタンス変数を、selfキーワードを使用して呼び出すプログラムを確認していきましょう。

ソースコード

ソース・フォルダー: /Desktop/Python基礎講座
ファイル名: 第3章.ipynb
アクセスURL: http://localhost:8888/notebooks/Desktop/Python基礎講座/第3章.ipynb

    #クラスPersonを定義
    class Person:
        #コンストラクタの定義
        def __init__(self,name,age):
            self.name = name
            self.age = age
        #メソッドの定義
        def share_self(self):
            print('名前:',self.name)
            print('年齢:',self.age,'歳')

    #インスタンスの生成
    person_1 = Person('田中',42)
    person_2 = Person('佐藤',32)

    #メソッドの呼び出し
    person_1.share_self()
    person_2.share_self()
	

実行結果

	名前: 田中
	年齢: 42 歳
	名前: 佐藤
	年齢: 32 歳
	

解説

2~10行目でクラスPersonを定義してます。

    class Person:
        #コンストラクタの定義
        def __init__(self,name,age):
            self.name = name
            self.age = age
        #メソッドの定義
        def share_self(self):
            print('名前:',self.name)
            print('年齢:',self.age,'歳')
	

8~10行目でコンストラクタ以外のメソッドを定義しており、第一引数にはselfを指定し、処理内ではコンストラクタ内で宣言したインスタンス変数のname、ageをselfを介して呼び出しています。

図 3.3.1:インスタンス変数の共有

メソッドshare_self内のself.nameには、コンストラクタ内のself.nameの値(nameの値)が参照され、メソッドshare_self内のself.ageコンストラクタ内のself.ageの値(ageの値)が参照されます。

13行目ではperson_1という変数を宣言し、Personから引数として(‘田中’、42)を指定したインスタンスを生成し、person_1にこのインスタンスを代入しています。
この(‘田中’,42)という値はそれぞれ、このインスタンスの中のコンストラクタの引数に代入されます。
14行目も同様に、person_2という変数を宣言しており、今度はPersonから引数として(‘佐藤’、32)を指定したインスタンスを生成し、person_2にこのインスタンスを代入しています。

    person_1 = Person('田中',42)
    person_2 = Person('佐藤',32)
	

13,14行目の処理をイメージで表現すると、以下の図 3.3.2のようになります。

図 3.3.2:インスタンスの生成

17,18行目では、person_1、person_2、それぞれのインスタンスから、別々にメソッドshare.self()を呼び出しています。
person_1のself.name、self.ageには「田中」、「42」が格納されており、share.self()はコンストラクタのselfを参照するので、share_self内のself.nameには「田中」、self.ageには「42」が格納されるため、先ほどのような実行結果が得られます。
17,18行目の処理をイメージで表現すると、以下の図 3.2.2のようになります。

    person_1.share_self()
    person_2.share_self()
	

図 3.3.3:メソッドの実行

3.3.4 self以外を第一引数に指定した場合の凡例

先ほどからお伝えしている通り、コンストラクタの第一引数にselfを指定する必要はなく、別の引数名を指定しても正常に動きます。またコンストラクタ以外のメソッドに関しても同様です。
以下ではself以外のものを第一引数に指定した例を紹介します。

凡例①:self以外の引数を指定したケース

実行結果

self以外の引数を指定した場合でも上記から同じ動作が行われていることがわかります。コンストラクタの引数textには「self以外の引数」が設定されているので、インスタンス変数text(com.text)には、「self以外の引数」が代入されています。
メソッドshow_self()では、インスタンス自身を表す引数としてcomが指定されているため、このメソッド内での「com.text」の「text」はコンストラクタの中で宣言されたインスタンス変数「text」と同じものです。
メソッドshow_self()は、このインスタンス変数の値を出力するものなので上記のような実行結果になります。

凡例②:コンストラクタ、メソッドで別々の第一引数を指定した場合

実行結果

実行結果からコンストラクタ、それ以外のメソッドで別々の第一引数を指定しても、同じような動作が行われていることがわかります。
コンストラクタの引数textには「別々の引数」が設定されているので、インスタンス変数text(com.text)には、「別々の引数」が代入されます。
一方、メソッドshow_self()では、第一引数にthisが指定されていますが、第一引数はインスタンス自身を表すものなので、このメソッド内での「this.text」の「text」はコンストラクタの中で宣言されたインスタンス変数「text」と同じものです。
メソッドshow_self()は、このインスタンス変数の値を出力するものなので上記のような実行結果になります。

ポイント

  • コンストラクタ内の第一引数は、インスタンス自身を表すものである。
  • コンストラクタ内の第一引数に、selfを指定しなくても動作するがselfを指定するのが一般的である。
  • 同じクラス内で他のメソッドと、インスタンス変数を共有することができ、他のメソッドでも第一引数を指定する必要があり、この第一引数もインスタンス自身を表すものである。
  • メソッドの第一引数もselfを指定する必要はないが、selfを指定するのが一般的である。

NEXT>> 3.4 本章のまとめ