Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 18, 2010 23:40:28

Cleric
От:
Зарегистрирован: 2007-06-26
Сообщения: 87
Репутация: +  0  -
Профиль   Отправить e-mail  

overloading-lib

Года 2-3 назад, после перехода на python (до этого я писал на C++), вдохновлённый PEP 3124, Я скорее для фана решил написать урезанный аналог для python`а ветки 2.x. И вот что из этого получилось…

Проект на google code
Запись в блоге с примерами использования

Библиотека динамической перегрузки функций и методов основанной на типах аргументов для языка python

Библиотека overloading определяет средства позволяющие писать перегруженные функции и методы в вашем коде. Весь функционал реализован в единственном модуле overloading.py.

Так-же стоит добавить что библиотека была вдохновлена PEP 3124, в ней нет и половины возможностей и расширяемости первоисточника, но я писал её скорее для фана (однако в дальнейшем я использовал её в нескольких своих проектах). В моём представлении она должна выполнять свою основную задачу, добавлять в язык перегрузку функций, основанную на типах аргументов, максимально близкую к реализации оной из C++. Т.е. от идеи включения в библиотеку реализации интерфейсов и прочего функционала, я отказался, сосредоточившись на перегрузке. Так как писал я библиотеку на чистом python'е и поиск функций происходит в runtime, то старался максимально сократить время поиска среди кандидатов, подходящей функции (Phillip J. Eby, автор PEP`а и библиотеки PEAK для оптимизации использовал Bytecode Assembler, а это сильная магия:))

Для определения перегруженной функции/метода существуют декораторы overload, и when, overload служит для определения перегруженной функции, сигнатура задается в параметрах декоратора, пример:
    @overload(float)
def func(x):
...
@overload(int)
def func(x):
...

func(1) # вызов функции с сигнатурой func(x: int)
func(1.0) # вызов функции с сигнатурой func(x: float)
При разрешении перегрузки используется полиморфизм:
    class MyStr(str): pass

@overload(str)
def func(x):
...

func("string") # вызов функции с сигнатурой func(x: str)
func(MyStr()) # вызов функции с сигнатурой func(x: str)
Декоратор overload в комбинации с mix-in классом Overloadable позволяет определять перегруженные методы, семантика аналогична использованию overload для функций (за исключением того что в сигнатуру метода не входит первый параметр self), пример:
    class T(Overloadable):

@overload(bool)
def meth(self, x):
...
@overload(int, str)
def meth(self, x, y):
...
i=T()
i.meth(1, 'hello') # вызов метода с сигнатурой meth(x: int, y: str)
i.meth(True) # вызов метода с сигнатурой meth(x: bool)
i.meth("Opps!") # исключение CannotResolve, метод с сигнатурой
# meth(x: str) не определен
Декоратор when позволяет определить перегруженную функцию/метод имя которой не совпадает с именем других перегруженных методов, пример:
@overload(bool)
def func(x):
...
@overload(int)
def func(x):
...
@when(func, (list,))
def func_list(x):
...

func(1) # вызов функции с сигнатурой func(x: int)
func(True) # вызов функции с сигнатурой func(x: bool)
func([1,2,3]) # вызов функции определенной с помощью декоратора when
func_list([1]) # явный вызов функции
Первым параметром декоратора должна быть перегруженная функция/метод, определенная ранее в данном пространстве имен, второй параметр кортеж из типов аргументов функции.
Определение обобщенной функции:

# Обобщенная функция
def func(x):
...

# Специализированные функции

@overload(int)
def func(x):
...
@overload(float)
def func(x):
...
func(1) # вызов функции с сигнатурой func(x: int)
func(1.0) # вызов функции с сигнатурой func(x: float)
func([1,2,3]) # вызов обобщенной функции
Обобщенная функция должна быть определена раньше её специализированных вариантов и в том же пространстве имен

Ограничения:
- Нет поддержки аргументов со значениями по умолчанию
- Нет поддержки переменного числа аргументов (*args)
- Нет поддержки именованных аргументов (**kwargs)
- Нет приведения типов, например int не будет приведен к float
- Декораторы overload и when несовместимы с любыми другими декораторами включая classmethod и staticmethod
Возможно, кому то будет интересно поэкспериментировать с библиотекой:)



Офлайн

#2 Сен. 19, 2010 03:53:30

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

overloading-lib

Самый первый вопрос - а зачем потребовался велосипед?
Чем PEAK-Rules нехорош?



Офлайн

#3 Сен. 19, 2010 10:59:39

Cleric
От:
Зарегистрирован: 2007-06-26
Сообщения: 87
Репутация: +  0  -
Профиль   Отправить e-mail  

overloading-lib

Всем хорош, а писалось это скорее для фана и закрепления языка:) Мне просто было интересно реализовать нечто подобное.



Отредактировано (Сен. 19, 2010 11:17:55)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version