Pythonのクラスの構造
記事の内容
この記事では、Pythonのクラス階層の構造について補足します。クラス階層の構造を知ると、プログラムの理解の幅が広がると思います。
1.Pythonのすべてのクラスはトップレベルのobjectクラスを継承して定義される
この記事が掲載されているPython入門-クラスオブジェクト編のマガジンでは、class宣言を使ったオブジェクトの定義(作成)や継承の方法について説明してきました。
自身のプログラムで新しくクラスを作成するときは、class文で、
class <クラス名>:
と宣言し、作成します。別のクラスを継承して作成する場合は、
class <クラス名>(<親クラス名>):
と宣言し、作成します。
他のクラスを継承しない場合、Python3系ではクラス名の後ろの()は省略することができます。しかし、class文で親クラスの指定を省略した場合は、実は自動的にobjectという名前の親クラスを継承してクラスを作成しています。
objectクラスは、Pythonで定義されるすべてのクラスの先祖、テンプレート、トップレベルのクラスなのです。すなわち、Pythonのすべてのクラスのトップは必ずobjectクラスということになります。この、トップレベルのクラス(object)をルートクラスとも呼びます。
Python2系のクラス宣言では、親クラスを省略できないので、新しくクラスを宣言する場合は
##python2系のクラス宣言(python3系でも動く)
class <クラス名>(object):
と宣言する必要があります。
2.クラスのプロパティ名とメソッド名を取得する
python組み込みのdir関数の引数にオブジェクトを渡して
dir(<オブジェクト>)
で呼び出すと、そのオブジェクトを定義するクラスのプロパティ名とメソッド名のリストを返します。
Pythonでクラスを継承すると、子クラスは親クラスのすべてのプロパティとメソッドを引き継ぎます。したがって、dir関数はobjectクラスのプロパティ名とメソッド名も返します。
サンプルコードでみててみましょう。
##class_keisho_ex4.py
##class宣言
class Kagensan:
##インスタンスコンストラクタの作成
def __init__(self, a, b):
self.x = a
self.y = b
##インスタンスメソッドの作成
def tashizan(self):
wa = self.x + self.y
self.wa = wa
return wa
def hikizan(self):
sa = self.x - self.y
return sa
def tashizan(a, b):
return a + b
##Kagensanクラスのプロパティとメソッドを出力
print(dir(Kagensan))
print("\n")
##Kagensanクラスのインスタンスのプロパティとメソッドを出力
a = 5
b = 3
ins = Kagensan(a, b)
print(dir(ins))
print("\n")
出力結果
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hikizan', 'tashizan']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hikizan', 'tashizan', 'x', 'y']
たくさんのプロパティ名、メソッド名が出力されました。
出力の1行目はKagensanクラスを引数としています。Kagensanクラスではtashizan、hikizanの2つのメソッドしか定義していないので、それ以外はすべてobjectクラスのプロパティやメソッドです。
出力の2行目はKagensanクラスのインスタンスを引数としています。インスタンス変数xとyは、インスタンスが生成されるときにはじめて定義されるので、引数にインスタンスを渡したときのみ出力されています。
出力結果を見ると、__new__や__init__などのコンストラクタもobjectクラスで定義されていることがわかります。__new__や__init__がコンストラクタとしてふるまうのは、objectクラスの中でそのように定義されているからです。
objectクラスの他のプロパティやメソッドも、調べてみるとより理解が深まるのではないでしょうか。