Перегружены функции в питоне? - PullRequest
79 голосов
/ 18 августа 2011

Возможно ли иметь перегруженные функции в Python? В C # я бы сделал что-то вроде

void myfunction (int first, string second)
{
//some code
}
void myfunction (int first, string second , float third)
{
//some different code
}

и затем, когда я вызываю функцию, она будет различаться между двумя в зависимости от количества аргументов. Возможно ли сделать что-то подобное в Python?

Ответы [ 5 ]

96 голосов
/ 18 августа 2011

РЕДАКТИРОВАТЬ Для новых универсальных функций единой отправки в Python 3.4, см. http://www.python.org/dev/peps/pep-0443/

Обычно вам не нужно перегружать функции в Python. Python динамически типизирован и поддерживает необязательные аргументы для функций.

def myfunction(first, second, third = None):
    if third is None:
        #just use first and second
    else:
        #use all three

myfunction(1, 2) # third will be None, so enter the 'if' clause
myfunction(3, 4, 5) # third isn't None, it's 5, so enter the 'else' clause
46 голосов
/ 18 августа 2011

в обычном питоне вы не можете делать то, что хотите.Есть два близких приближения:

def myfunction(first, second, *args):
    # args is a tuple of extra arguments

def myfunction(first, second, third=None):
    # third is optional

однако, если вы действительно хотите сделать это, вы, безусловно, можете заставить это работать (рискуя оскорбить традиционалистов; o).короче говоря, вы бы написали функцию wrapper(*args), которая проверяет количество аргументов и делегатов в зависимости от ситуации.этот вид "взлома" обычно делается с помощью декораторов.в этом случае вы могли бы получить что-то вроде:

from typing import overload

@overload
def myfunction(first):
    ....

@myfunction.overload
def myfunction(first, second):
    ....

@myfunction.overload
def myfunction(first, second, third):
    ....

и реализовать это, заставив overload(first_fn) функцию (или конструктор) вернуть вызываемый объект, где __call__(*args) метод выполняет делегирование, описанное выше, а метод overload(another_fn) добавляет дополнительные функции, которые могут быть делегированы.

Вы можете увидеть пример чего-то подобного здесь http://acooke.org/pytyp/pytyp.spec.dispatch.html но это перегрузка методов по типу.это очень похожий подход ...

ОБНОВЛЕНИЕ: и что-то подобное (с использованием типов аргументов) добавляется в Python 3 - http://www.python.org/dev/peps/pep-0443/

7 голосов
/ 24 октября 2014

Да, это возможно. Я написал код ниже в Python 3.2.1:

def overload(*functions):
    return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

Использование:

myfunction=overload(no_arg_func, one_arg_func, two_arg_func)

Обратите внимание, что лямбда, возвращаемая функциями overload, выбирает функцию для вызова в зависимости от количества неназванных аргументов.

Решение не идеальное, но сейчас я не могу написать ничего лучше.

1 голос
/ 18 августа 2011

Не возможно напрямую.Вы можете использовать явные проверки типов для приведенных аргументов, хотя это обычно осуждается.

Python является динамическим.Если вы не уверены в том, что может сделать объект, просто попробуйте: и вызовите для него метод, затем исключите: ошибки.

Если вам не требуется перегрузка на основе типов, а только на количество аргументов, используйтеключевые аргументы.

0 голосов
/ 30 декабря 2016

перегрузка методов сложна в Python.Однако может использоваться передача переменных dict, list или примитивов.

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

Давайтевозьмем пример использования в одном из потоковых потоков:

метод перегрузки класса с вызовом методов из другого класса.

def add_bullet(sprite=None, start=None, headto=None, spead=None, acceleration=None):

передача аргументов из удаленного класса:

add_bullet(sprite = 'test', start=Yes,headto={'lat':10.6666,'long':10.6666},accelaration=10.6}

ИЛИ add_bullet(sprite = 'test', start=Yes,headto={'lat':10.6666,'long':10.6666},speed=['10','20,'30']}

Итак, выполняется обработка для списка, словаря или примитивных переменных из-за перегрузки метода.

tryэто для ваших кодов

...