Java/Python 導入ガイド《8》組み込み関数 isinstance を使って
Java プログラマーのための Python 導入ガイド〈初級/入門編〉《Jython2.5.0》
《8》組み込み関数 isinstance を使って
》作業中です《 2006年7月 5日 (水)
組み込み関数 isinstance を使って
前の《事例》では、list/set/dict ごとに、異なる関数 list_filter/set_filter/map_filter を用意する必要がありました。なぜなら、イテレーションの最中に要素を削除しようとすると、set/dict では問題が生じるからです。そこで、組み込み関数 filter を使うなら、その問題を回避できるだけでなく、共通するフレームワークを提供する準備が整います。すると、異なる関数を統合するのが容易になり、それは、次のようになります。
>>> def xfilter(c):
... for e in filter(lambda e: not cond(e), c):
... if isinstance(c, dict):
... del c[e]
... else:
... c.remove(e)
組み込み関数 filter を使うと、引数 c が list/set/dict のいずれにも対処できます。しかし、メソッドの本体では、組み込み関数 isinstance を使って、dict に固有の処理を分別しているので、改善の余地があります(後の記事で紹介します)。
《Note》組み込み関数 isinstance
isinstance(object, class-or-type-or-tuple) -> bool組み込み関数 isinstance は、object が指定した(子孫)クラス class のインスタンスかどうかを判定した結果をリターン値にします。クラスの代わりに型 type を指定すると、それが object の型かどうかを判定します。
>>> isinstance(3,int) True
整数 3 の型は int なので、True が得られます。
>>> isinstance([],list) True >>> isinstance({},dict) True空リスト [] の型は list であり、空辞書 {} の型は dict であるのが分かります。
>>> class Parent: pass >>> class Child(Parent): pass >>> c,p = Child(),Parent() >>> isinstance(c,Parent); isinstance(p,Child) True Falseクラス Child の親は Parent です。すると、c は、親クラス Parent のインスタンスと見なせますが、p は、子クラス Child のインスタンスとは見なせません。また、次のように、
>>> for e in list,set,dict: ... n = e.__name__ ... s = "isinstance(%s,%s)"%(eval("%s()"%n),n) ... print s,":",eval(s) isinstance(,list) : True isinstance(set(),set) : True isinstance({},dict) : True
組み込み型 list/set/dict と、それぞれの空インスタンスとの関係が分かります。
リスト:list
>>> c = range(5)
>>> c
[0, 1, 2, 3, 4]
>>> xfilter(c)
>>> c
[1, 3]
関数 xfilter を使うと、リスト c から、奇数でない要素だけが削除され、期待した副作用が得られたのが分かります。
集合:set
>>> c = set(range(5))
>>> c
set([0, 1, 2, 3, 4])
>>> xfilter(c)
>>> c
set([1, 3])
関数 xfilter を使うと、集合 c から、奇数でない要素だけが削除され、期待した副作用が得られたのが分かります。
写像:dict
>>> c = dict([(k,v) for k,v in enumerate("ABCDE")])
>>> c
{0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E'}
>>> xfilter(c)
>>> c
{1: 'B', 3: 'D'}
関数 xfilter を使うと、辞書 c から、奇数でないキー要素を含む要素対だけが削除され、期待した副作用が得られたのが分かります。