LoginSignup
20
23

More than 5 years have passed since last update.

Python 3.4.0 の新機能 (3) - Single-dispatch generic functions

Last updated at Posted at 2014-03-30

今日は Single-dispatch generic functions (PEP-443)。Generic functionは汎用関数と訳されることも多いが、言語によって微妙に違う使われ方をしている。Pythonでは「引数の型によって動作が異なる複数の関数に同じ名前をつける」という意味合いで使われているようだ。

と書いてもさっぱりわからないので、例示。引数の型によって出力が異なる関数を考える。Generic functionsを使わないとこんな感じ。

def print_func(arg):
    arg_type = type(arg)
    if arg_type is int:
        print("found integer:", arg)
    elif arg_type is list:
        print("found list:", arg)
    else:
        print("found something:", arg)

print_func(1)
print_func(['a','b','c'])
print_func(1.23)

入力された引数の型をif文で一つずつチェックしながら処理する。
実行結果はこう。

found integer: 1
found list: ['a', 'b', 'c']
found something: 1.23

これを、Single-dispatch generic functionsで書くとこうなる。

from functools import singledispatch

@singledispatch
def print_func(arg):
    print("found something:", arg)

@print_func.register(int)
def _(arg):
    print("found integer:", arg)

@print_func.register(list)
def _(arg):
    print("found list:", arg)

print_func(1)
print_func(['a','b','c'])
print_func(1.23)

ベースになる関数をsingledispatch decoratorで修飾し、それに型ごとの処理をregisterメソッドを使って追加していく感じ。どちらが良いのかは微妙だが、型ごとの処理がもっと長くなる場合は一つのif文に入れるよりもこちらの方がすっきりするかも。

結果は上と一緒なので省略。

にしてもあまり使い道が思いつかない。ある値を見てDispatchするのはよくやっていて、例えばHeaderの値からその後に続くデータの形式がわかるのでそういうデータ群のparsingとか。そういう場合は、値から関数を引くDictを用意して実現することが多いが、これは型だもんなぁ。

20
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
23