SlideShare a Scribd company logo
Effective Python
読書会 #4
オズ@Wizard_of_Oz__
Effective
Python
項目28
カスタムコンテナ型はcollections.abcを継承する
単純なユースケースの場合
• Listにメソッドを加えたい
– 要素の頻度を数えるメソッド
– Listを継承したサブクラスを作る
class FrequencyList(list):
def __init__(self, members):
super().__init__(members)
def frequency(self):
counts = {}
for item in self:
counts.setdefault(item, 0)
counts[item] += 1
return counts
単純なユースケースの場合
• Listを継承したサブクラスを作る
– Listの標準機能がすべて使える
foo = FrequencyList([‘a’, ‘b’, ‘a’, ‘c’, ‘b’, ‘a’, ‘d’])
print (‘Length is’, len(foo))
foo.pop()
print(‘After pop:’, repr(foo))
print(‘Frequency:’, foo.frequency())
>>>
Length is 7
After pop: [‘a’, ‘b’, ‘a’, ‘c’, ‘b’, ‘a’]
Frequency: {‘a’ : 3, ‘c’ : 1, ‘b’ : 2}
継承しない場合
• サブクラスではない形でセマンティクスを提供
– 二分木クラスにシーケンスのセマンティクスを提供
class BinaryNode(object):
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
シーケンスの振る舞いの実装
• Pythonはコンテナの振る舞いを
特別な名前を持ったインスタンスメソッドで実装
– シーケンスに添字でアクセス
bar = [1, 2, 3]
bar[0]
– Pythonの解釈
bar.__getitem__(0)
BinaryNodeクラスを
シーケンスのように振る舞わせる
• __getitem__の実装を提供する
– 二分木クラスにシーケンスのセマンティクスを提供
class IndexableNode(BinaryNode):
def _search(self, count, index):
....
# Returns (found, count)
def __getitem__(self, index):
found, _ = self._search(0, index)
if not found:
raise IndexError('Index out of range')
return found.value
BinaryNodeクラスを
シーケンスのように振る舞わせる
class IndexableNode(BinaryNode):
def _search(self, count, index):
found = None
if self.left:
found, count = self.left._search(count, index)
if not found and count == index:
found = self
else:
count += 1
if not found and self.right:
found, count = self.right._search(count, index)
return found, count
# Returns (found, count)
def __getitem__(self, index):
found, _ = self._search(0, index)
if not found:
raise IndexError('Index out of range')
return found.value
BinaryNodeクラスを
シーケンスのように振る舞わせる
• IndexableNode
– 通常の二分木として構築できる
– Listのようにアクセスできる
print('LRR =', tree.left.right.right.value) #LRR = 7
print('Index 0 =', tree[0]) #Index 0 = 2
print('Index 1 =', tree[1]) #Index 1 = 5
print('11 in the tree?', 11 in tree) #11 in the tree? True
print('17 in the tree?', 17 in tree) #17 in the tree? False
print('Tree is', list(tree)) #Tree is [2, 5, 6, 7, 10, 11, 15]
__getitem__を実装した場合の問題点
• シーケンスのセマンティクス全てを提供するには不十分
– __len__という特別なメソッドが必要
len(tree)
>>>
TypeError: object of type ‘IndexableNode’ has no len()
独自のコンテナ型を定義するのは困難
• 他にも特別なメソッドの定義が必要
– countやindexというメソッドが足りない
• collections.abcモジュール
– 典型的なメソッドをすべて提供する抽象基底クラス
– 必要なメソッドの実装がないと教えてくれる
from collections.abc import Sequence
class BadType(Sequence):
pass
foo = BadType()
>>>
TypeError: Can’t instantiate abstract class BadType with abstract methods __getitem__,
__len__
独自のコンテナ型を定義するのは困難
try:
from collections.abc import Sequence
class BadType(Sequence):
pass
foo = BadType()
except:
logging.exception('Expected')
else:
assert False
>>>
TypeError: Can’t instantiate abstract class BadType with abstract methods __getitem__,
__len__
collections.abc
• 抽象基底クラスに必要な全てのメソッドを実装
– 追加メソッドが提供される(indexやcountなど)
– 複雑な型(SetやMutableMapping等)で特に有用
– 実装が必要な特殊メソッドの個数が膨大
class BetterNode(SequenceNode, Sequence):
pass
tree = BetterNode(...)
print('Index of 7 is', tree.index(7)) #Index of 7 is 3
print('Count of 10 is', tree.count(10)) #Count of 10 is 1
まとめ
• 単純なユースケースはPythonのコンテナ型から直接継承
– コンテナ型:listやdictなど
• カスタムコンテナ型を正しく実装するには多数のメソッドが必要
• カスタムコンテナ型はcollections.abcで定義されたインタフェースを継承する
– 必要なインタフェースを備えていることを確かなものにするため

More Related Content

PDF
Python勉強会3-コレクションとファイル
PDF
これからの「言語」の話をしよう ―― 未来を生きるためのツール
PDF
Gensim
PDF
Introduction Xtend
PDF
すごいHaskell読書会#1 in 大阪
PDF
R入門(dplyrでデータ加工)-TokyoR42
PDF
PDF
F#入門 ~関数プログラミングとは何か~
Python勉強会3-コレクションとファイル
これからの「言語」の話をしよう ―― 未来を生きるためのツール
Gensim
Introduction Xtend
すごいHaskell読書会#1 in 大阪
R入門(dplyrでデータ加工)-TokyoR42
F#入門 ~関数プログラミングとは何か~

What's hot (19)

PDF
Boostライブラリ一周の旅
PDF
Scalaのオブジェクトの話
PDF
I phoneアプリ入門 第5回
PDF
Elixirだ 第1回 - 基礎だ -
PDF
Elixirだ 第2回
PDF
Juliaで並列計算
PDF
10分で分かるr言語入門ver2.10 14 1101
PDF
Python勉強会4-制御構文とパッケージ
PDF
10分で分かるr言語入門ver2.9 14 0920
PDF
Elixirだ 第1回強化版 前半
PDF
Elixirだ 第1回強化版 後半
PDF
Juliaによる予測モデル構築・評価
PDF
FP習熟度レベルとFSharpxのIteratee
PDF
Pythonで始めるDropboxAPI
PPT
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
PPTX
20071030
PDF
Metaprogramming in JuliaLang
PDF
たのしい高階関数
PDF
アルゴリズム+データ構造勉強会(9)
Boostライブラリ一周の旅
Scalaのオブジェクトの話
I phoneアプリ入門 第5回
Elixirだ 第1回 - 基礎だ -
Elixirだ 第2回
Juliaで並列計算
10分で分かるr言語入門ver2.10 14 1101
Python勉強会4-制御構文とパッケージ
10分で分かるr言語入門ver2.9 14 0920
Elixirだ 第1回強化版 前半
Elixirだ 第1回強化版 後半
Juliaによる予測モデル構築・評価
FP習熟度レベルとFSharpxのIteratee
Pythonで始めるDropboxAPI
12-11-30 Kashiwa.R #5 初めてのR Rを始める前に知っておきたい10のこと
20071030
Metaprogramming in JuliaLang
たのしい高階関数
アルゴリズム+データ構造勉強会(9)
Ad

Viewers also liked (14)

PDF
DGR Guidance on Auto Enrolment Jan 2017
PPTX
Relacion de economia con diversas ciencias
PPTX
Mauro Libi Crestani: Team Avelina presente en la edición 52 de la Vuelta al T...
PPTX
Monastero
PDF
Culture and forching
PPTX
Don't need docker
PPT
Fellesforelesning uke5
PPTX
Redes locales de economía social y solidaria
PPTX
MH CET 2017
PPTX
O level work energy and power
PDF
LCR REPORT_EN_WEB
PDF
Work, power, and energy
PDF
Site Plan: Barkingside
PPT
Fracciones equivalentes MATERIAL PARA IMPRIMIR
DGR Guidance on Auto Enrolment Jan 2017
Relacion de economia con diversas ciencias
Mauro Libi Crestani: Team Avelina presente en la edición 52 de la Vuelta al T...
Monastero
Culture and forching
Don't need docker
Fellesforelesning uke5
Redes locales de economía social y solidaria
MH CET 2017
O level work energy and power
LCR REPORT_EN_WEB
Work, power, and energy
Site Plan: Barkingside
Fracciones equivalentes MATERIAL PARA IMPRIMIR
Ad

Similar to Effective python#28 (20)

PPTX
Introduction to Functional Programming
PDF
多次元配列の効率的利用法の検討
PDF
Scala2.8への移行
PDF
Scala2.8への移行
PDF
Python入門
PDF
S02 t1 sta_py_tsuji_0702_slides
PDF
ALPSチュートリアル(4) Python入門
PDF
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
ODP
これから Haskell を書くにあたって
PDF
Gura プログラミング言語の紹介
PDF
関数型プログラミング入門 with OCaml
PDF
Ruby 3の型推論やってます
PDF
Python for Data Anaysis第2回勉強会4,5章
KEY
ひのきのぼうだけで全クリ目指す
PDF
エキ Py 読書会02 2章前半
PDF
プログラミング言語Scala
PDF
Scalaプログラミング・マニアックス
PDF
Pythonはどうやってlen関数で長さを手にいれているの?
PDF
これから Haskell を書くにあたって
PDF
ウェーブレット木の世界
Introduction to Functional Programming
多次元配列の効率的利用法の検討
Scala2.8への移行
Scala2.8への移行
Python入門
S02 t1 sta_py_tsuji_0702_slides
ALPSチュートリアル(4) Python入門
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
これから Haskell を書くにあたって
Gura プログラミング言語の紹介
関数型プログラミング入門 with OCaml
Ruby 3の型推論やってます
Python for Data Anaysis第2回勉強会4,5章
ひのきのぼうだけで全クリ目指す
エキ Py 読書会02 2章前半
プログラミング言語Scala
Scalaプログラミング・マニアックス
Pythonはどうやってlen関数で長さを手にいれているの?
これから Haskell を書くにあたって
ウェーブレット木の世界

Effective python#28