파이썬에서 오버로드 된 함수?


92

파이썬에서 오버로드 된 함수를 가질 수 있습니까? C #에서는 다음과 같이 할 것입니다.

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

그런 다음 함수를 호출하면 인수 수에 따라 둘을 구분합니다. 파이썬에서 비슷한 일을 할 수 있습니까?


중복 게시물 일 수 있습니다. 또한 질문이 C #과 관련이 없으므로 C #으로 플래그를 지정하지 마십시오. 기능 - 과부하 -에 - 파이썬 - 실종
이드로


답변:


103

편집 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

3
그러나 인수 유형 에 따라 다른 함수를 호출하는 것은 훨씬 더 어렵습니다 (불가능하지는 않지만).
Andrew Jaffe

9
글쎄요, 과부하 / 다형성과 조건부 사이에는 차이가 있습니다. 조건문이 있기 때문에 다형성이 필요하지 않다는 뜻입니까?
Val

1
@Val 기본적으로 동적 형식 언어에서는 코드에서 간단하게 에뮬레이션 할 수 있기 때문에 언어 기능으로 오버로딩이 필요하지 않으므로 다형성을 얻을 수 있습니다.
agf

1
@Val 저는 선택적 인수와 동적 유형 사이에 Python에서 사용하는 방식으로 다형성을 달성하기 위해 Java 스타일 메서드 오버로딩이 필요하지 않다고 말합니다.
agf

3
@navidoo 나는 그것이 좋은 생각이 아니라고 주장합니다. 함수는 완전히 다른 유형의 것을 반환하지 않습니다. 그러나 항상 메인 함수 내부에 로컬 생성기 함수를 정의하고 호출 한 다음 결과 생성기를 반환 할 수 있습니다. 외부에서 보면 메인 함수가 생성기 인 것처럼 동일합니다. 여기에 예.
agf

50

정상적인 파이썬에서는 원하는 것을 할 수 없습니다. 두 가지 근사치가 있습니다.

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에서 유사한 예제를 볼 수 있지만 유형별로 메서드가 오버로드됩니다. 매우 유사한 접근 방식입니다 ...

업데이트 : 그리고 비슷한 것 (인수 유형 사용)이 파이썬 3에 추가되었습니다-http: //www.python.org/dev/peps/pep-0443/


range내장 그래서 정말 해킹, 과부하를 사용? github.com/python/typeshed/blob/master/stdlib/2and3/…
CptJero

9

예, 가능합니다. 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

직접 불가능합니다. 비록 이것은 일반적으로 눈살을 찌푸 리지만 주어진 인수에 대해 명시 적 유형 검사를 사용할 수 있습니다.

Python은 동적입니다. 객체가 무엇을 할 수 있는지 확실하지 않은 경우 다음을 시도해보십시오 : 오류를 제외하고 메서드를 호출하십시오.

유형에 따라 오버로드 할 필요가 없지만 인수 수에 따라 오버로드 할 필요가없는 경우 키워드 인수를 사용하십시오.


3
나는 그가 선택적 인수에 대해 알지 못했다고 생각합니다.
agf

0

오버로딩 메서드는 파이썬에서 까다 롭습니다. 그러나 사전, 목록 또는 기본 변수를 전달하는 용도가있을 수 있습니다.

나는 내 유스 케이스를 위해 무언가를 시도했는데, 이것은 사람들이 메소드를 과부하시키는 것을 이해하는 데 도움이 될 수 있습니다.

stackoverflow 스레드 중 하나에서 사용 예제를 보겠습니다.

다른 클래스의 메서드를 호출하는 클래스 오버로드 메서드.

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']}

따라서 메서드 오버로딩에서 목록, 사전 또는 기본 변수에 대한 처리가 이루어집니다.

당신의 코드를 위해 그것을 시도

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.