ㅍㅍㅋㄷ

Python3 - Function annotation 에 대하여 본문

Programming/Python

Python3 - Function annotation 에 대하여

클쏭 2019. 6. 20. 01:18

 

Function annotation 은 무엇인가

 어떤 언어이든 장점과 단점이 공존하기 마련이다.

 Python 의 경우 문법의 제약성이 적음으로 인해 유연성이 높은 장점을 취하였지만 반대로 그로 인해 발생되는 불편함도 있다.

 변수나 함수 사용시 자료형에 대한 선언이 없고 자유롭게 사용이 가능하기 때문에 작성된 코드를 볼때 명시적으로 해석이 어려운 부분이 있다. 

 annotation 은 이러한 불편한 점을 조금이나마 덜기 위해 나온 기능이다.

 

Function annotation 의 사용 방법

  function annotation 은 python3 이상에서 사용 가능하다. 

  사용 방법은 비교적 간단하다.

  annotation 문법을 사용해 function 을 정의하는 아래 예제를 보자.

# Fuctnion annotation
def func(arg1: str, arg2: 1+2, arg3: 'this is annotation') -> bool
    

   위와 같이 파라미터에 : expression 형태로 매개변수 마다 annotation 을 쓸 수 있다. 

   annotation 에는 arg1 처럼 매개변수의 type 을 써놓을 수도 있고,

   arg2 의 annotation 처럼 덧셈과 같은 간단한 연산 표현도 작성 가능하며, 

   arg3 처럼 string 형태로도 작성 가능하다. 

 

   또한, function 의 return 값에 대해서는 -> expression 형태로 사용한다. 

   return 또한 매개변수와 사용 방법은 동일하다.

 

Function annotation 의 특징

   annotation 의 가장 큰 특징은 바로 강제성이 없다는 것이다. 

   즉, annotation 이라는 말그대로 주석일 뿐이며 해당 code 자체에는 어떠한 영향도 미치지 않는다. 

   

   아래 예를 보자.

# test.py 
# Fuctnion annotation

def func(arg1: str, arg2: 1+2, arg3: 'this is annotation') -> bool
    print(f'arg1 = {arg1}')
    print(f'arg2 = {arg2}')
    print(f'arg3 = {arg3}')

    return True

result = func('test1', 3, 'this is test')
print(f'result = {result}')

   annotation 을 활용해 func 라는 함수를 작성 후 func 함수를 호출 후 그 결과를 반환하는 스크립트이다. 

   결과는 아래와 같다.

> python3 test.py
arg1 = test1
arg2 = 3
arg3 = this is test
result = True

 

  만약, 함수에 작성된 annotation 과 무관한 인자를 넣어 호출하면 어떻게 될까.

  아래와 같이 annotation 과 상관없는 'test1', 'test2', 'test3' 라는 인자를 넣어 func2 를 호출해 보자.

# test.py 
# Fuctnion annotation

def func2(arg1: str, arg2: 1+2, arg3: 'this is annotation') -> bool
    print(f'arg1 = {arg1}')
    print(f'arg2 = {arg2}')
    print(f'arg3 = {arg3}')

    return True

result = func2('test1', 'test2', 'test3')
print(f'result = {result}')

  그 결과는 아래와 같이 정상 동작함을 볼 수 있다.

> python3 test.py
arg1 = test1
arg2 = test2
arg3 = test3
result = True

 즉, annotation에 적혀 있는 내용은 주석이므로 실제로는 이와 상관없이 실행되게 된다.

 

 그리고, annotation 은 해당 함수의 __annotation__ 의 속성에서 정보를 확인해 볼 수 있다.

# test.py 
# Fuctnion annotation

def func(arg1: str, arg2: 1+2, arg3: 'this is annotation') -> bool
    print(test.__annotations__)

    return True

result = func('test1', 3, 'this is test')
print(f'result = {result}')

 

결과는 아래와 같다.

> python3 test.py
{'arg1': <class 'str'>, 'arg2': 3, 'arg3': 'this is annotation', 'return': <class 'bool'>}
result = True

 

Function annotation 의 장점

 annotation 의 장점이라고 한다면, 

 함수의 매개변수와 반환값을 명시적으로 보여준다는데 있다.

 python은 언어의 특성상 변수의 자료형을 명시적으로 지정하지 않기 때문에 사용성이 간편하고 유연한 대신 코드의 명확성은 떨어지는 단점이 있다.

 보통 그래서 function 을 작성할때 아래와 같이 주석(comment)를 달아 개발자간 커뮤니케이션에 쓰이긴 하지만 이것 또한 지속적으로 작성하기 쉽지 않은게 현실이다. (귀찮...)

# Fuctnion with comments
def func(arg1, arg2, arg3):
    '''    
    :param arg1: str
    :param arg2: str
    :param arg3: list
    :return: bool
    '''

 

 그리고 function annotation 는 IDE 를 사용할때 좀 더 추가적인 장점이 발휘된다. 

 

 다음 예제를 보자.

 아래는 pycharm 을 통해 작성한 User 라는 class 이다.

 ( 참고로 이 User 는 mongoengine 을 활용하여 document 를 정의한 것이다. )

[User 클래스]

 그리고 이 User class 를 user 라는 변수에 인스턴스로 생성해 보면 아래와 같이 자동 완성으로 참조되는 것을 볼 수 있다.

 

  하지만 해당 User class를 dynamic import 를 사용하거나 다른 방식으로 import 하였을 경우

  IDE 에서 이를 인식하지 못하는 경우가 종종 발생한다.

 

  아래는 get_model 이라는 메소드를 통해 dynamic 하게 User 를 가져온 것이라 IDE 에서 제대로 인식하지 못한 경우이다.  

 

  이때 annotation 을 활용해 명시적으로 해당 변수를 지정하는 경우, IDE 에서 인식 가능하다.

 

 

Reference

 

 

 

 

 

 

 

 

 

Comments