Select Language

AI Technology Community

7.4、Python selfの使い方

オブジェクトの属性は、クラスの外部では「オブジェクト名.属性」で表され、クラスの内部では「self.属性」で表されます。オブジェクトの属性には、追加、削除、変更、検索の操作があります。たとえば、代入文を使って属性を変更または追加することができ、del()を使ってオブジェクトの属性を削除することができます。

属性の追加は、Pythonのような動的言語では非常に簡単です。追加するタイミングに制限はなく、実行時に追加することも、作成時に追加することもできます。一方、C++やJavaのような静的言語では、属性の数と種類はクラス定義時に決定され、その後は変更することができません。実行時には属性の値のみを変更することができます。

以下は、コンストラクタで属性を追加する例です。

>>> class Student:
...     version = "1.0"
...     author = "python.cn"
...     def __init__(self):
...         self.name = ""
...                              # クラス定義終了
>>> student_a = Student()        # クラスのインスタンスオブジェクトを作成
>>> student_a.name               # nameの値を確認
''


以下は、メンバ関数で属性を追加する例です。

>>> class Student:
...     version = "1.0"
...     author = "python.cn"
...     def __init__(self):
...         self.name = ""        # 新しく追加された属性name
...     def add_attr_age(self, val):
...         self.age = val
...
>>> student_a = Student()
>>> hasattr(student_a, "age")
False
>>> student_a.add_attr_age(18)
>>> hasattr(student_a, "age")
True


もちろん、クラスの外部でオブジェクトに属性を追加することもできます。

>>> class Student:
...     version = "1.0"
...     author = "python.cn"
...     def __init__(self):
...         self.name = ""
...                                  # クラス定義終了
>>> student_a = Student()
>>> hasattr(student_a, "age")        # 現在、このインスタンスオブジェクトには属性ageがありません
False
>>> student_a.age = 18               # このインスタンスオブジェクトに新しい属性ageを追加
>>> hasattr(student_a, "age")
True

これが動的言語の利点です。オブジェクトの属性は事前に定義されているわけではなく、実行中に属性を追加したり、変更したり、削除したりすることができます。

実際、Pythonでは、変数と関数の地位は同じです。これは、オブジェクトのメソッドを追加することもできることを意味します。ただし、オブジェクトメソッドの最初の引数は必ずselfで、現在のオブジェクトを表します。

>>> class Student:
...     version = "1.0"
...     author = "python.cn"
...     def __init__(self):
...         self.name = ""
...     def method1(self):
...         print("Inside method1()")
...     def method2(self):
...         print("Inside method2()")
...     def method(self):
...         print("Old One")
...     def update_method(self, val):
...         if val == 1:
...             self.method = self.method1      # methodメソッドを変更
...         else:
...             self.method = self.method2
...
>>> student_a = Student()
>>> student_a.method()                 # 変更前
Old One
>>> student_a.update_method(1)         # method1関数に変更
>>> student_a.method()
Inside method1()
>>> student_a.update_method(2)         # method2関数に変更
>>> student_a.method()
Inside method2()


もちろん、クラスの外部の関数をクラスの関数にすることもできます。この場合、外部関数の__self__属性を指定する必要があります。この属性は、その関数が所属するオブジェクトを示します。以下のコードは、この使い方を簡単に示していますが、最善の方法はクロージャを使うことです。

>>> def obj_method():
...     print("Inside obj_method()")
...     print("obj.name = [%s]" % obj_method.__self__.name)
...                                                                             # 関数定義終了
>>> class Student:
...     version = "1.0"
...     author = "python.cn"
...     def __init__(self):
...         self.name = ""
...     def update_method(self, val):
...         self.new_method = val
...         val.__self__ = self
...                                                                             # クラス定義終了
>>> student_a.get_highest_score                # これは通常の関数
<function get_highest_score at 0x1047cc848>
>>> student_a.set_score                                        # これはオブジェクトのメソッド
<bound method Student.set_score of <__main__.Student instance at
        0x1047c7e18>>
>>> student_a = Student()
>>> hasattr(student_a, "new_method")
False
>>> student_a.update_method(obj_method)
>>> hasattr(student_a, "new_method")
True
>>> student_a.new_method()
Inside obj_method()
obj.name = []


post
  • 10

    item of content
前の章では、リストや辞書などのPythonの予め定義されたデータ型について説明しました。しかし、自分で新しいタイプを定義したい場合、クラスを使用する必要があります。つまり、クラスを使用することで自分だけのデータ型を定義でき、システムで定義された型だけを使う以上のことができます。
クラスはオブジェクト指向プログラミングにおいて非常に基本的な概念であり、最も基本的な機能は新しいデータ型を作成することです。さらに、クラスAから新しいクラスBを派生させることができ、その際クラスBはクラスAのすべての属性を継承します(これを継承機能と呼びます)。
この章では、クラスの定義と使用方法について説明します。具体的には、クラスのプロパティとメソッド、クラスの派生方法、多重継承の使用方法などを解説します。