calendarcodediamondfacebookfingerglobalgoogleplushatenahomepagetopplainpocketrssservicetwitterwordpresshome2searchfoldernext-arrowback-arrowfirst-arrowlast-arrow

Python : クラスの使い方 2(継承、super()、多重継承、Mixin)

継承とは、クラスを定義する際に基底クラスを指定することで、基底クラスの性質を受け継ぎ、コードの再利用を実現する方法である。

エンジニア速報は Twitter の@commteで 1 日 5 回配信しています。

Sponsored Link

目次

クラスの継承のポイント

クラス名の後に(基底クラス名)と指定する。

class Car: pass class Sedan(Car): pass
  • 基底クラスとは親クラスのこと
  • サブクラスとは基底クラスを継承したクラス
  • 継承により基底クラスの性質を継承した子クラスを定義できる
  • 新しいメソッドと変数を追加できる
  • 基底クラスのメソッドを上書きできる

クラスがほかのクラスを継承したかどうかは、issubclass() を使って判定する。

class Car: pass class Sedan(Car): pass issubclass(Sedan, Car) # True

それぞれのクラスからインスタンスを作り、name メソッドを呼び出してみると、基底クラスを継承していることが分かる。

class Car: def name(self): print('私は車です。') class Sedan(Car): # Car を継承 pass car = Car() sedan = Sedan() car.name() # 私は車です。 sedan.name() # 私は車です。

super()

メソッドのオーバーライドとは、基底クラスが持つメソッドと同名のメソッドを定義することによって、そのメソッドを上書することである。

class クラス名(基底クラス): def __init__(self, 引数): super().__init__(引数) 処理

オーバーライドしたメソッドでは、基底クラスのメソッドが自動で呼ばれないので、明示的に呼び出す必要がある。基底クラスのメソッドを呼び出すときは、呼び出し先の関数のブロック内に、組み込み関数 super() を記述する。

class Car: def __init__(self, name): self.name = name class Color(Car): # Car を継承 def __init__(self, name, color): # color 引数を追加 super().__init__(name) # 基底クラスのメソッド呼び出し self.color = color # 基底クラスに含まれていない要素 sedan = Color('CROWN', 'BLACK') sedan.name # 'CROWN' sedan.color # 'BLACK'

上に書いたコードが行っているのは、以下である。

  1. super()が基底クラスの定義を取り出す
  2. super().__init__(name) メソッドが、Car.__init__(name) メソッドを呼び出す
  3. 引数 color が、基底クラスに渡され処理される

将来、基底クラスの定義が変更されても、super()を使っていれば、基底クラスから継承している属性やメソッドは、その変更を反映したものになる。

# 基底クラス(継承元) class Parent: def __init__(self, a, b): self.a = a self.b = b def w (self): return self.b # 継承先 class Child(Parent): def w(self): # メソッドのオーバーライド return super().w() child = Child(0, 'hello') child.w() # 'hello'
# 基底クラス(継承元) class Parent: def __init__(self, name, age): self.name = name self.age = age def my_name(self): print("名前は" + self.name + "。年齢は" + str(self.age) + "歳。") # 継承先 class Child(Parent): def __init__(self, name, age): super().__init__(name, age) # オーバーライド def my_hello(self): print("こんにちは") # インスタンス化 yamada = Child("山田", 20) yamada.my_name() yamada.my_hello() # 名前は山田。年齢は20歳。 # こんにちは

多重継承

基底クラスに複数のクラスを指定する。基底クラスをカンマ区切りで並べると多重継承になる。Python の継承は、メソッド解決順序により決まる。

class A: def __init__(self, name): self.name = name def method(self): print('A') return self.name class B: def __init__(self, name): self.name = name def method(self): print('B') return self.name class C(A, B): pass c = C('ccc') c.method() # A # ccc

ひし形継承問題

以下のように複数の継承元が同じメソッド名にすると競合が起きる。無謀な継承は避けるべきである。

class A: def hello(self): print('hello A') class B(A): def hello(self): print('hello B') super().hello() class C(A): def hello(self): print('hello C') super().hello() class D(B, C): def hello(self): print('hello D') super().hello() d = D() d.hello() # hello D # hello B # hello C # hello A

Mixin

Mixin (ミックスイン)とは、もとのクラス階層とは直接的に関連しない処理をまとめたものである。つまり、クラス定義にヘルパーとして使うだけの親クラスを組み込むことができる。次に示すコードは、Python の標準ライブラリである pprint モジュールをインポートして、pprint.pprint() メソッドを使い、オブジェクトをきれいに整形して出力する例である。

import pprint class Mixin: def feature(self): pprint.pprint(vars(self)) class Taro(Mixin): pass f = Taro() f.name = 'yamada' f.age = 17 f.broad = 'B' f.feature() # {'age': 17, 'broad': 'B', 'name': 'yamada'}

クラスの基本操作はこちら

Python おすすめ本

スポンサード リンク

Comments

Leave a Comment

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください