2016-09-28 4 views
0

Существует пакет overloading для Python 3.5+. В этом пакете можно переопределить методы, но с различными типами намеков и его декоратором будет выяснен, какой перегруженный метод следует вызывать.Python 3.5 - перегрузка метода с помощью @overload

Общий шаблон кодирования:

class foo: 
    def func(param): 
    if instance(param, int): 
     pass 
    elif instance(param, str): 
     pass 
    elif instance(param, list): 
     pass 
    else: 
     raise ValueError() 

С @overload:

class foo: 
    @overload 
    def func(param: int): 
    pass 

    @overload 
    def func(param: str): 
    pass 

    @overload 
    def func(param: list): 
    pass 

Вот documentation.


Мои вопросы:

  • Насколько велика влияние на производительность по сравнению с переключением типа параметра по старому стилю?
  • И как этот пакет получает доступ к подсказкам типа?
+2

* Общий шаблон кодирования * - Нет, это не так, извините. Для большинства Python-кода не нужно использовать 'isinstance()'. –

+0

Обратите внимание, что пакет не относится к Python 3.5. Python 3.5 содержит только стандартные типы подсказок, но аннотации доступны с Python 3.0 и далее. Пакет, который вы связываете с поддержкой 3,3 и выше; ваш пример вообще не использует модуль 'typing'. –

+0

[исходный код] (https://github.com/bintoro/overloading.py/blob/master/overloading.py) должен дать вам ответ на второй вопрос (он читает аннотации функций, как и ожидалось). Глядя на 'dispatcher()', я бы пошел с «медленнее» для первого. –

ответ

1

Вам придется измерять его самостоятельно с помощью реального кода.

Я очень быстро просмотрел код этой библиотеки, и вывод прост. Он использует много отражений (проверка пакета) и сравнение типов. проверка пакета сама по себе в основном используется средствами отладки - они всегда замедляют ваш код.

Только посмотрите на эти строки:

complexity = complexity_mapping[id] 
if complexity & 8 and isinstance(arg, tuple): 
    element_type = tuple(type(el) for el in arg) 
elif complexity & 4 and hasattr(arg, 'keys'): 
    element_type = (type(element), type(arg[element])) 
else: 
    element_type = type(element) 

type_hints = typing.get_type_hints(func) if typing else func.__annotations__ 
types = tuple(normalize_type(type_hints.get(param, AnyType)) for param in parameters) 

Обратите внимание, что этот пакет, если в течение 7 месяцев и имеет только 70 звезд. Python - это не Java ... Вы действительно повредили бы сам python с этим пакетом: D Вам лучше реализовать некоторый основной метод api, который делегирует вызовы другим методам/объектам на основе параметров типа - точно так же, как это должно быть сделано с Python ,