Python 3.0 Hacks
第2回 abcモジュールによる抽象基底クラスの作成
抽象クラスとインターフェース
C++には,
抽象クラスとは,
このような抽象クラスを用いることは,
Python においては,
似たような挙動をさせるには, 未実装であることの印としてNotImplementedオブジェクトを返すことがありますが,
abcモジュールによる抽象クラス
そのような状況だったPythonですが,
このモジュールは,
抽象クラスの定義
まずはこのモジュールを使用して,
リスト1
#-*- coding:utf-8 -*-
import abc
class BaseShape(object, metaclass=abc.ABCMeta):
''' 形を定義するための基底クラス '''
@abc.abstractmethod
def getSize(self):
''' 面積を計算して返す抽象メソッド '''
pass
リスト1では, BaseShapeというクラスを定義しています。これは,
通常のクラス定義と違うのは,
abstructmethodというデコレータは,
同様のデコレータにabstractpropertyというものがあります。これは,
次に,
それでは,
リスト2
>>> BaseShape()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class BaseShape with abstract methods getSize
すると,
abcモジュールのメタクラス処理
メタクラスでカスタマイズできるのは,
それでは,
- メタクラスの処理でabstractmethod/
abstractpropertyで設定した印を見て, クラスオブジェクトの__ abstractmethods__という属性に抽象メソッドの名前のfrozensetを保存 - インスタンスを作成する際に,
クラスが__ abstractmethods__を持ち, 何らかの名前が入っていれば, 例外を投げる
そのため,
klass.__abstractmethods__ = {'aaa', 'bbb'}
というように,
継承とオーバライド
ここで, BaseShape クラスを継承して,
リスト3
import math
class Circle(BaseShape):
''' 円を定義 '''
def __init__(self, radius):
self.radius = radius
def getSize(self):
''' 面積を計算 '''
return self.radius ** 2 * math.pi
今回は,
このCircleクラスを実際に使用してみます。
リスト4
>>> b = Circle(10)
>>> print(b.getSize())
314.159265359
このようにインスタンスが作成でき,
バックナンバー
Python 3.0 Hacks
- 最終回 Python 3.0座談会(動画つき)
- 第11回 標準になったjsonモジュール
- 第10回 argument"s" clinic
- 第9回 Python3にもC拡張モジュールを─Python3.0でも使える拡張モジュール開発手法の確立
- 第8回 リスト処理と内包表記
- 第7回 関数アノテーションでスマートにプラスアルファの実現
- 第6回 Pythonicな文字列フォーマットforamat()メソッド
- 第5回 multiprocessingモジュールによるプロセス間通信
- 第4回 「俺様プチencoding」を実装して理解するPython3.0のioとcodec,encodingの機構
- 第3回 turtleモジュールで図と戯れる