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: 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 위치