[python] 파이썬에서 메소드 오버로딩을 어떻게 사용합니까?

파이썬에서 메소드 오버로드를 구현하려고합니다.

class A:
    def stackoverflow(self):
        print 'first method'
    def stackoverflow(self, i):
        print 'second method', i

ob=A()
ob.stackoverflow(2)

그러나 출력은 second method 2; 비슷하게:

class A:
    def stackoverflow(self):
        print 'first method'
    def stackoverflow(self, i):
        print 'second method', i

ob=A()
ob.stackoverflow()

준다

Traceback (most recent call last):
  File "my.py", line 9, in <module>
    ob.stackoverflow()
TypeError: stackoverflow() takes exactly 2 arguments (1 given)

이 작업을 어떻게합니까?



답변

그것은의 메소드 오버로딩은 방법이 아니다 오버라이드 (override) . 그리고 파이썬에서는 하나의 함수로 모든 것을 수행합니다.

class A:

    def stackoverflow(self, i='some_default_value'):
        print 'only method'

ob=A()
ob.stackoverflow(2)
ob.stackoverflow()

파이썬에서 같은 이름을 가진 두 개의 메소드를 가질 수 없으며 필요하지 않습니다.

Python 튜토리얼 의 기본 인수 값 섹션을 참조하십시오 . 피해야 할 일반적인 실수 는 “최소한의 놀라움”과 가변성 기본 인수 를 참조하십시오 .

편집 : Python 3.4의 새로운 단일 디스패치 일반 함수에 대한 정보는 PEP 443 을 참조하십시오 .


답변

pythonlangutil 을 사용할 수도 있습니다 .

from pythonlangutil.overload import Overload, signature

class A:
    @Overload
    @signature()
    def stackoverflow(self):
        print 'first method'

    @stackoverflow.overload
    @signature("int")
    def stackoverflow(self, i):
        print 'second method', i


답변

파이썬에서는 그런 식으로 일을하지 않습니다. 사람들이 Java와 같은 언어로 그렇게 할 때 일반적으로 기본값을 원합니다 (그렇지 않으면 일반적으로 다른 이름을 가진 메소드를 원합니다). 따라서 파이썬에서는 기본값을 가질 수 있습니다 .

class A(object):  # Remember the ``object`` bit when working in Python 2.x

    def stackoverflow(self, i=None):
        if i is None:
            print 'first form'
        else:
            print 'second form'

보시 다시피이 값을 사용하면 단순히 기본값이 아닌 별도의 동작을 트리거 할 있습니다.

>>> ob = A()
>>> ob.stackoverflow()
first form
>>> ob.stackoverflow(2)
second form


답변

당신은 할 필요가 없으며, 정말로 필요하지도 않습니다.

파이썬에서는 모든 것이 객체입니다. 클래스는 사물이므로 객체입니다. 방법도 있습니다.

A클래스 라는 개체가 있습니다 . 라는 속성이 stackoverflow있습니다. 그러한 속성은 하나만 가질 수 있습니다.

을 쓸 때 def stackoverflow(...): ...발생하는 것은 메소드 인 객체를 생성하여 stackoverflow속성에 할당하는 것입니다 A. 두 개의 정의를 작성하면 두 번째 정의가 첫 번째 정의를 대체하며 할당은 항상 동작하는 방식과 동일합니다.

또한 오버로딩이 때때로 사용되는 더 많은 종류의 작업을 수행하는 코드를 작성하고 싶지 않습니다. 언어가 작동하는 방식이 아닙니다.

대신, (어쨌든 함수 매개 변수 유형을 지정하지 않기 때문에 거의 의미)이 제공 될 수있는 것은 각 유형에 대해 별도의 함수를 정의하기 위해 노력 정지 일들이 무엇인지에 대한 걱정 이다 그들이 할 수 있는지에 대해 생각하기 시작 수행하십시오 .

튜플 대 목록을 처리하기 위해 별도의 것을 작성할 수있을뿐만 아니라 원하지 않거나 필요하지도 않습니다 .

당신이하는 일은 둘 다 반복 가능하다는 것 (즉, 쓸 수 있음 for element in container:)을 활용하는 것입니다. (그들이 상속과 직접 관련이 없다는 사실은 관련이 없습니다.)


답변

@agf가 PEP-3124로 과거의 대답에 옳았지만 구문 설탕을 얻었습니다. 데코레이터 에 대한 자세한 내용타이핑 설명서를 참조하십시오. @overload이것은 실제로 구문 설탕이며 IMHO는 그 이후로 사람들이 논쟁 해 온 모든 것입니다. 개인적으로 나는 다른 서명 여러 기능을 가지는 것은 다음 20 개 이상의 인수를 기본 값으로 모든 설정 (단일 기능을 갖는 더 쉽게 읽을 동의 None끝없는 사용하여 주변에 바이올린을 가진 후 대부분의 시간) 및 if, elif, else알아 체인 무엇 호출자는 실제로 함수가 제공된 인수 세트와 관련되기를 원합니다. 이것은 파이썬 선을 따라 오랜 시간이 지났습니다

못생긴 것보다 아름답습니다.

그리고 틀림없이

단순보다 복잡합니다.

위에 링크 된 공식 파이썬 문서에서 직접 :

from typing import overload
@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> Tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    <actual implementation>


답변

파이썬 3.2.1로 답을 씁니다.

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

작동 방식 :

  1. overload호출 가능한 양을 가져와 tuple에 저장 functions한 다음 람다를 반환합니다.
  2. 람다는 임의의 양의 인수를 취한 다음 functions[number_of_unnamed_args_passed]람다에 전달 된 인수와 함께 호출 된 함수에 저장된 호출 결과를 리턴합니다 .

용법:

class A:
    stackoverflow=overload(                    \
        None, \
        #there is always a self argument, so this should never get called
        lambda self: print('First method'),      \
        lambda self, i: print('Second method', i) \
    )


답변

찾고있는 단어가 “오버로딩”이라고 생각합니다. 파이썬에서는 메소드 오버로드가 없습니다. 그러나 다음과 같이 기본 인수를 사용할 수 있습니다.

def stackoverflow(self, i=None):
    if i != None:
        print 'second method', i
    else:
        print 'first method'

인수를 전달하면 첫 번째 조건의 논리를 따르고 첫 번째 print 문을 실행합니다. 인수를 전달하지 않으면 else조건으로 이동 하여 두 번째 print 문을 실행합니다.