Мультидиспетчеризация с generic
Сегодня выпустил версию 0.1 библиотеки для обобщённого программирования (generic programming) на языке Python с оригинальным названием generic.
Одно из возможных применений этой библиотеки — создание мультиметодов.
Мультиметод — это такая функция, которая меняет своё поведение в зависимости от типов переданных ей аргументов, то есть, действует примерно следующим образом:
def show(arg):
if isinstance(arg, str):
return show_str(arg)
elif isinstance(arg, int):
return show_int(arg)
def show_str(arg):
return "str: %s" % arg
def show_int(arg):
return "int: %d" % arg
С использование generic это делается так:
from generic.multidispatch import multifunction
@multifunction(str)
def show(arg):
return "str: %s" % arg
@show.when(int)
def show(arg):
return "int: %d" % arg
show(1) # returns 'int: 1'
show("s") # returns 'str: s'
show([]) # raises TypeError
На мой взгляд, получается более элегантно. К тому же, мы всегда можем расширить наш мультиметод другими реализациями для других типов аргумента, чего не сделаешь с функцией из первого примера.
Также можно определять мультиметоды с диспетчеризацией по нескольким аргументам:
@multifunction(int, int)
def add(x, y):
return x + y
@add.when(str, str)
def add(x, y):
return add(int(x), int(y))
К сожалению, пока библиотека может создавать мультиметоды только из обычных функций (не методов), такие вот получаются “мультифункции”. В дальнейшем эту ситуацию планируется исправить.
Установить generic можно с помощью easy_install обычным образом:
easy_install generic
Репозиторий с исходным кодом и багтрекер находится на github. Пока там около 200 строк кода вместе с докстрингами и примерно такое же количество тестов.