사용툴 분석

Union이 뭐고 왜 사용하는가?

필만이 2024. 11. 8. 14:56

UnionPython의 typing 모듈에서 제공하는 타입 어노테이션으로, 변수나 함수의 매개변수, 반환값이 여러 타입 중 하나일 수 있음을 나타낼 때 사용됩니다. Union을 통해 코드에서 여러 타입을 허용해야 할 때 가독성을 높이고, 타입 안정성을 강화할 수 있습니다.

Union의 주요 특징

  1. 다양한 타입 허용: Union은 타입을 제한하면서도 여러 타입을 허용할 수 있어, 함수나 클래스가 다양한 입력을 유연하게 처리할 수 있도록 해줍니다. 예를 들어, Union[int, str]는 해당 변수나 매개변수가 int 또는 str 타입일 수 있음을 나타냅니다.

  2. 타입 안전성 강화: Union을 사용하면 코드 내에서 여러 타입의 데이터를 허용하면서도 각 타입에 맞는 처리를 할 수 있어, 잘못된 타입 사용을 방지할 수 있습니다. 타입 검사기 (예: mypy)나 IDE가 자동으로 타입을 추론하고 오류를 감지할 수 있도록 도와줍니다.

  3. 가독성 향상: 코드에 타입 힌트를 명확히 제공해, 함수의 매개변수나 반환값이 여러 타입 중 하나일 수 있음을 다른 개발자에게 쉽게 전달할 수 있습니다.

기본 문법

from typing import Union

# age는 int 또는 str 타입이 될 수 있습니다.
def process_age(age: Union[int, str]) -> int:
    if isinstance(age, str):
        age = int(age)  # 문자열을 정수로 변환
    return age

위 코드에서 process_age 함수는 intstr 타입의 age를 입력으로 받을 수 있으며, 반환값은 항상 int입니다.

Union 사용 예시

예시 1: 문자열 또는 정수를 받아 처리하는 함수

어떤 함수가 정수와 문자열 모두를 받아 처리할 수 있도록 하고 싶다면, Union을 사용해 이러한 의도를 명확히 할 수 있습니다.

from typing import Union

def parse_number(value: Union[int, str]) -> int:
    """정수 또는 숫자 문자열을 입력 받아 정수로 반환"""
    if isinstance(value, str):
        return int(value)  # 문자열을 정수로 변환
    return value  # 이미 정수인 경우 그대로 반환

print(parse_number(42))      # 42
print(parse_number("123"))   # 123
  • parse_number 함수는 intstr을 입력받아 숫자로 변환합니다.
  • Union[int, str]을 통해 두 타입을 모두 지원함을 명시하여, 다양한 입력을 받을 수 있습니다.

예시 2: 여러 타입의 반환값을 갖는 함수

어떤 함수가 사용자 데이터를 찾으면 dict를, 찾지 못하면 None을 반환하도록 설계할 수 있습니다. 이때, Union[dict, None]을 사용하여 함수의 반환 타입을 명확히 할 수 있습니다.

from typing import Union, Optional

def find_user(user_id: int) -> Optional[dict]:  # Optional[dict]는 Union[dict, None]의 단축형
    """사용자 ID로 사용자 정보를 검색하고 없으면 None을 반환"""
    user_db = {1: {"name": "Alice"}, 2: {"name": "Bob"}}
    return user_db.get(user_id)  # 존재하지 않으면 None 반환

result = find_user(1)
if result:
    print("User found:", result["name"])
else:
    print("User not found")
  • find_user 함수는 dict 또는 None을 반환할 수 있으며, Optional[dict](또는 Union[dict, None])로 타입을 지정해 호출자에게 반환 타입에 대한 힌트를 제공합니다.

Union을 사용할 때 주의할 점

  1. 타입 확인 필요:

    • Union을 사용해 여러 타입을 허용할 경우, 함수 내에서 isinstancetype을 사용하여 타입을 확인하고, 각 타입에 맞는 처리를 해주어야 합니다.
  2. 호환되지 않는 타입 주의:

    • Union을 사용할 때, 서로 호환되지 않는 타입(예: strint)을 동시에 사용하면 타입별로 처리 로직을 분리해야 합니다. 그렇지 않으면 런타임에서 예외가 발생할 수 있습니다.
  3. Optional과의 관계:

    • Optional[X]Union[X, None]의 단축형입니다. 즉, Optional[int]Union[int, None]와 동일하게 동작합니다.

Union의 실제 사용 예시

예시 3: 여러 타입의 매개변수를 지원하는 데이터 처리 함수

from typing import Union

def display_info(data: Union[str, list]) -> None:
    """문자열 또는 리스트를 입력 받아 출력"""
    if isinstance(data, str):
        print(f"String data: {data}")
    elif isinstance(data, list):
        print(f"List data: {', '.join(map(str, data))}")

display_info("Hello, World!")       # 문자열 처리
display_info([1, 2, 3, 4, 5])       # 리스트 처리
  • display_infostr 또는 list 타입을 받아 각 타입에 맞게 데이터를 출력합니다.
  • Union을 사용해 다양한 타입을 받으면서도, 타입별로 다른 처리를 할 수 있습니다.

예시 4: 클래스에서 여러 타입의 속성을 지원하는 경우

from typing import Union

class ValueContainer:
    def __init__(self, value: Union[int, float, str]):
        self.value = value

    def display(self) -> None:
        if isinstance(self.value, (int, float)):
            print(f"Numeric value: {self.value}")
        elif isinstance(self.value, str):
            print(f"String value: {self.value}")

# 다양한 타입의 인스턴스 생성 및 출력
val1 = ValueContainer(42)
val2 = ValueContainer(3.14)
val3 = ValueContainer("Hello")

val1.display()  # Numeric value: 42
val2.display()  # Numeric value: 3.14
val3.display()  # String value: Hello
  • ValueContainer 클래스는 다양한 타입을 가진 value 속성을 지원하며, Union[int, float, str]로 정의하여 int, float, str을 모두 받을 수 있습니다.
  • display 메서드는 타입에 따라 다른 출력 형식을 제공합니다.

요약

Union은 여러 타입을 허용하여 유연한 데이터 처리와 가독성을 동시에 제공합니다. 특히 함수의 매개변수나 반환값에 여러 타입이 예상될 때 유용하며, 데이터 유형에 따라 다른 처리를 할 수 있도록 구현할 수 있습니다.