Published on

[Python] 파이썬의 def 오버로딩에 대해

Authors
  • avatar
    Name
    Almer Minified
    Twitter

[Python] 파이썬의 def 오버로딩에 대해

파이썬의 def 오버로딩에 대해 알아보기

같은 이름의 함수가 오버로드되면 파이썬은 특정 오류 메시지를 표시하지 않고 마지막으로 정의된 함수 이름에 따라 마음대로 처리한다. 예를 들어보면

  def init_function(): 
      print('init_function') 
  def init_function(arg=5): 
      print('init_function:',arg) 
  init_function() 
  init_function(1)

이 경우에

>>> init_function: 5 
init_function: 1

위의 경우, 나중에 정의하는 init_function(arg=5) 함수가 호출되어 연산을 수행했다. 그래서 다음처럼 순서를 바꿔보자.

def init_function(arg=5): 
  print('init_function:', arg) 
def init_function():
  print('init_function') 
  init_function() # 일반 호출 
  init_function(1) # 오류 발생
  

이렇게하면 트레이스백이 발생할 것이다.

>>> TypeError: init_function() takes 0 positional arguments but 1 was given

나중에 정의된 "init_function()"를 유효한 함수로 간주하기 떄문에 "init_function(1)"을 호출할 때 예외가 발생하는 것이다. 이런 규칙은 instance나 static 함수에도 적용된다. 예를 들어 다음과 유사한 instance나 static 함수를 정의해보자

class MyType(object): @staticmethod def init_function(arg): # 같은 이름의 함수가 뒤에 정의되었으므로 이건 무시된다 
  print('static init_function') 
def init_function(self, arg): # 이게 실질적으로 작동하는 함수이다
  print('instance init_function:', arg) 
get_type = MyType()
get_type.init_function(6) # 성공적으로 인스턴스 함수를 호출할 것이다
MyType.init_function(5) # 스태틱 함수는 무시되었으므로 제대로 호출되지 않는다

이제 어떻게 되는 것인지 알겠는가?

class MyType(object): 
def init_function(self, arg): # 작동안함
  print('instance init_function:', arg) 
@staticmethod def init_function(arg): # 이게 작동한다
  print('static init_function') 
get_type = MyType()
get_type.init_function(6) # 스태틱 함수 실행 
MyType.init_function(5) # 스태틱 함수 실행

이러면 에러는 발생하지 않는다 둘다 staticmethod를 호출하기 때문이다. 근데 파이썬의 내재적인 관점에서 보면 클래스 내에서 instance나 static 함수는 아무런 차이가 없다. 정적 함수에 붙여진 데코레이터 @staticmethod는 임의로 만든 데코레이터 클래스에 불과하다. 더 근본적으로 파이썬은 모든 형을 딕셔너리 데이터형으로 취급한다. 그래서 결국 키/값일 뿐입니다. 따라서 다음과 같이 하면,

        def name_test(): 
            print('name_test') 
          async def name_test(arg): 
            print('name_test async def',arg) 
          item = None 
          func = None 
          for item in globals().keys(): 
            func = globals()[item].isinstance(func, types.FunctionType) is False:
            continue print(func)
>>>  function name_test 함수의 위치

파이썬 딕셔너리의 키도 str이다. 그래서 함수 이름만 포함하고 있고, 기술적으로는 "def name_test()"와 "async def name_test()"는 모두 "name_test" 키를 사용하기 떄문에 구별할 방법이 없게 된다. 또한 이 제한 때문에 같은 이름의 함수와 클래스를 정의할 수 없는 것이다.

def name_test(): # 나중에 정의된 같은 이름의 테스트 클래스가 있으므로 안쓰게 된다 
  print('name_test') 

class name_test(object): 
  # 클래스 유형을 마지막으로 정의된 "name_test" 키의 값으로 정의하게 된다 나중에 정의됐으므로. 
  pass 
  v = name_test() 
  # 함수를 호출하는게 클래스 인스턴스를 생성하는 것과 동일한 구문을 가진다. 
  # "name_test"라는 이름의 마지막 정의가 클래스였다. 그러므로 
  # 클래스 객체를 생성한다. 
  print(v)
  >>> [파일명].name_test 오브젝트 at 함수위치 # 이게 출력 결과이다.

결국 파이썬의 __dict__에는 전역 변수, 함수, 클래스 및 포함된 import 모듈에 대한 정보가 포함되어 있다. 게다가 이 모든 것이 "name" 키 아래에 등록되어 있으므로 마지막으로 정의한 것만 사용되게 된다.

        init_function = 'name_test' # 변수가 유효하지 않음: init_function 함수가 나중에 정의되었기 때문. 
        def init_function(): # 유효: 이전 init_function 변수를 재정의. 
          print('do-func') module =
          importlib.import_module(__name__) item = None for
          module.__dict__.keys() if item == 'init_function': print(item,
          module.__dict__[item])
          >>> init_function 함수 init_function at 위치