Select Language

AI Technology Community

7.3、Pythonクラスのプロパティとインスタンスのプロパティ

実は、クラス自体もオブジェクトであり、独自の属性を持っています。クラスの属性は一般的に、クラスに関連する内容、たとえばクラスのバージョンや作者などの情報を表します。クラスの属性を定義するには、クラスの中で直接変数を定義すればよいです。

以下では、クラスStudentにバージョンと作者の情報を追加します。

>>> class Student:                             # クラスStudentを定義
...     version = "1.0"                 # クラスの属性version
...     author = "python.cn"    # クラスの属性author
...
>>> Student                                            # クラスStudentを確認
<class '__main__.Student'>
>>> Student.version                            # クラスの属性を確認
'1.0'
>>> Student.author                             # クラスの属性を確認
'python.cn'

クラスの属性のアクセス方法は「クラス名。属性名」であることがわかります。これらの属性は変更することもできます。たとえば、Studentクラスのversion属性を変更することができます。

>>> Student.version = "1.1"            # クラスStudentの属性versionを変更
>>> Student.version                    # 変更後のクラスStudentの属性versionの値を確認
'1.1'


では、クラスの関数を定義することはできるでしょうか?実はできます。以下のコードのStudentクラスには、独自のクラス関数info()があります。

>>> class Student:                # クラスStudentを定義
...     version = "1.0"
...     author = "python.cn"
...     def info():               # クラスの関数を定義
...         print("version %s, author: %s" % (Student.version,
        Student.author))
...
>>> hasattr(Student, "info")      # info属性が存在するか
True
>>> Student.info                  # info属性を確認
<function Student.info at 0x105cb09d8>
>>> Student.info()                # info属性を使用
version 1.0, author: python.cn

インスタンス属性

Pythonはオブジェクト指向の言語であり、たとえ最も単純な整数であってもオブジェクトであり、独自のIDと属性を持っています。このセクションでは、オブジェクトとは、自作のクラスで作成されたオブジェクトを指します。

インスタンスオブジェクトはクラスに基づいて作成されるため、オブジェクトはクラスの属性を継承します。以下の例では、オブジェクトが自動的にクラスのすべての属性を継承することがわかります。

>>> class Student:                             # クラスStudentを定義
...     version = "1.0"
...     author = "python.cn"
...     def info():
...         print("version %s, author: %s" % (Student.version, Student.
author))
...
>>> student_a = Student()              # オブジェクトstudent_aを作成
>>> student_a.version                  # student_aの属性version
'1.0'
>>> student_a.author                   # student_aの属性author
'python.cn'


注意すべきは、これらのクラスから継承されたオブジェクトはコピーされたものではなく、クラスの属性を指しているということです。idを確認することで、この点を確認できます。

>>> id(student_a.version)     # オブジェクトのクラスから継承されたある属性は、対応するクラス属性と等しい
48991624
>>> id(Student.version)
48991624
>>> student_a.version is Student.version    # それらは同じオブジェクトである
True


また、クラス属性を変更することで、インスタンスが継承した属性も変化することを確認できます。

>>> student_a.version                  # オブジェクト属性
'1.0'
>>> Student.version = "1.1"            # クラス属性を変更
>>> student_a.version                  # オブジェクト属性も変化した
'1.1'


ただし、オブジェクトの属性を変更しても、クラスの属性には反映されません。以下の例では、オブジェクトの属性authorを変更しましたが、クラスStudentのauthor属性は変化していません。

>>> student_a.author = "inst_author"   # オブジェクトのauthor属性を変更
>>> student_a.author                   # オブジェクトのauthor属性が変化した
'inst_author'
>>> Student.author                     # クラスのauthor属性は変化していない
'python.cn'


特殊なケースとして、リストデータ型は、idを変更せずに内容を変更することができます。たとえば、append()インターフェース関数を呼び出すと、リストのidは変化せず、内容が変化します。以下にこのケースを示します。

>>> list_1 = []               # リストを作成
>>> list_1                    # リストの内容を確認
[]
>>> id(list_1)                # そのidを確認
48545224
>>> list_1.append(2)          # 要素を追加
>>> id(list_1)                # idは変化しない
48545224
>>> list_1                    # ただし、内容は変化した
[2]


このようなタイプの属性の場合、idが変化しない限り、オブジェクトがクラスから継承した属性を変更すると、クラス属性の値も変化します。以下のコードに示すとおりです。

>>> class Student:                           # クラスStudentを定義
...     years = []
...     def __init__(self):                  # コンストラクタ
...         print("__init__() is Running")
...     def __del__(self):                   # デストラクタ
...         print("__del__() is Running")
...     def append(self, element):           # 要素を追加
...         self.years.append(element)
...     def change(self, list):              # オブジェクトを変更
...         self.years = list
...                                                                             # クラス定義終了
>>> student_a = Student()      # オブジェクトを作成
__init__() is Running
>>> student_a.years
[]
>>> id(student_a.years)        # オブジェクト属性とクラス属性が同じidを持つことがわかる
490897

post
  • 10

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