Python) 람다 함수의 타입 검사

Lapis0875·2023년 5월 24일

Python

목록 보기
1/1
post-thumbnail

람다 함수에 대해...

람다 함수가 뭐에요? 라는 질문에 답해주다가 문득 생각이 들었어요. def 로 선언한 함수와 lambda로 선언한 익명함수 둘 다 함수 객체지만, 타입 힌트는 def에만 사용할 수 있죠. 그렇다면, 람다 함수를 거쳐 반환값을 변수에 할당한다면 이때 타입 검사는 어떻게 되는가? 가 궁금해졌어요.

실험해봐요

pyright를 사용해 타입 검사를 진행했어요. 사용한 코드는 모두 기재해뒀으니, 참고해주세요!

1 - 람다 함수 vs def 함수

def square_def(x):
    return x ** 2

square_lambda = lambda x: x ** 2

a: int = 5
b = square_lambda(a)
c = square_def(a)

def test(b: str) -> None:
    print(type(b))

test(b)
test(c)

💡 사용한 코드는 여기 에서 직접 확인할 수 있어요!

test(c)에서는 int형을 str형 매개변수에 쓸 수 없다는 오류가 발생해요. 하지만, test(b)는 타입 오류가 발생하지 않아요.

위 코드의 경우, test(c)에서만 타입 오류가 발생해요.

square_def의 경우, def로 선언했을 뿐 별도의 타입 힌트를 쓰지 않았으니 실질적으로 타입 정보는 lambda로 선언한 square_lambda와 같을거라 생각했어요. 하지만, square_def의 경우 c의 타입이 int로 정상적으로 추론되었지만 square_lambda의 경우 b의 타입이 추론되지 않았어요. 람다 함수가 타입 정보를 지우는걸까요?

2 - Callable 타입힌트

그렇다면, square_lambda라는 람다 함수를 담은 변수 자체에 타입 힌트를 걸어보면 어떨까요?

from typing import Callable

def square_def(x):
    return x ** 2

square_lambda: Callable[[int], int] = lambda x: x ** 2

a: int = 5
b = square_lambda(a)
c = square_def(a)

def test(b: str) -> None:
    print(type(b))

test(b)
test(c)

💡 사용한 코드는 여기 에서 직접 확인할 수 있어요!

🔎 Callable은 '호출 가능한 객체'에 대한 타입 힌트에요.
Callable[[int], int]의 경우, int형 매개변수 하나를 받아 int형을 반환하는 호출 가능한 객체의 타입 힌트에요.

이제는 test(b)에서도 int형을 str형 매개변수에 쓸 수 없다는 오류가 발생해요.

아까랑 다르게, test(b)에서도 타입 오류가 발생해요. 앞서 타입 정보를 추론하지 못했던 square_lambda에 Callable을 활용해 타입 힌트를 제공하니, b의 타입이 int로 추론되었다는 뜻이에요.

결론

위를 통해, 아래와 같은 결론을 얻었어요.

  • 동일한 형태의 함수더라도, 타입 힌트 없는 def 함수는 추론 가능하지만 람다함수는 추론 불가능하다.
  • 람다 함수더라도 람다 함수를 변수에 담아 Callable 타입 힌트를 제공하면, 타입 추론 가능하게 만들 수 있다.

타입 안전한 파이썬을 위해, 람다 함수를 쓸 때는 Callable 타입 힌트를 함께 사용해보는게 좋을 것 같아요 😄

profile
새내기 대학생 개발자에요 :D

0개의 댓글