반응형

공식문서에 따르면 Python에서는 함수나 변수 타입의 annotation을 강제하지 않는다. annotation이란 type hint를 생각하면 된다.

[c++]

int do_something(int x)
{
	return x + 1;
{

do_something이란 함수에 대해서 input parameter와 함수의 return 타입은 모두 int형으로 이를 어길시 에러가 발생한다.

[Python]

def do_something(x: int) -> int:
	return x + 1


print(do_something(1.1))  # 2.1

하지만 python의 경우 type hint를 어겨도 에러가 발생하지 않고, 위의 예와 같이 input parameter의 float 인 1.1을 넣어줘도 함수의 내용에 따라 2.1이 반환된다. 

 

하지만 annotation으로 에러가 발생하는 경우도 있는데 아래와 같이 forward reference와 연관된 경우이다. Forward reference란 메소드에서 변수를 먼저 사용하고, 그 이후에 변수를 정의하는 것이다. 

class A:
    def __init__(self, a: A):
        pass

# NameError: name 'A' is not defined

class A를 정의할 때, __init__ 메소드에서 parameter로 a를 받고 이는 class A라고 annotation이 표시되어있다. 하지만 위의 코드와 같이 작성하면 NameError가 발생하는데 그 이유는 class A의 정의가 끝나지 않는 상태에서 __init__ 메소드에서 사용하기 때문이다. 

위 문제를 해결하기 위해 크게 2가지가 있다.

1) type hint를 string으로 작성

class A:
    def do_something(self, a: 'A'):
        pass

아래의 코드를 통해서 해당 메소드의 annotation을 확인할 수 있다. 

print(A().do_something.__annotations__)  # {'a': 'A', 'return': None}

 

2) Python 3.7 이상 버전에서 from __future__ import annotations 추가

from __future__ import annotations

class A:
    def do_something(self, a: A) -> None:
        pass

class A의 정의가 끝나지 않는 상황에서 A를 annotation으로 사용하지만 에러가 발생하지 않는다.

아래의 코드를 통해 해당 메소드의 annotation들을 확인해보면 자동으로 string으로 변환된 것을 알 수 있다.

print(A().do_something.__annotations__) # {'a': 'A', 'return': None}

 

반응형

+ Recent posts