반응형
주요 타입 힌트와 함수 설명

ch02_ex5.py에서 자주 쓰이는 타입 힌트와 함수 설명

1. isinstance()

  • 파이썬 내장 함수로, 객체가 특정 클래스(혹은 그 하위 클래스)의 인스턴스인지 확인할 때 사용합니다.
  • 문법: isinstance(객체, 클래스)
  • 여러 타입을 튜플로 전달 가능: isinstance(x, (int, float))
class A: pass
class B(A): pass
b = B()
print(isinstance(b, A))  # True (B는 A의 하위 클래스)

2. cast() (typing 모듈)

  • 정적 타입 검사기(예: mypy)에게 "이 값은 내가 지정한 타입이라고 간주해라"라고 알려주는 용도입니다.
  • 런타임에는 아무런 변환도 하지 않고, 값 자체를 그대로 반환합니다.
  • 잘못된 타입을 cast해도 런타임 오류는 발생하지 않지만, 실제 사용 시 타입이 맞지 않으면 AttributeError 등은 발생할 수 있습니다.
from typing import cast

def foo(x: object):
    y = cast(str, x)  # 타입 검사기에게 y는 str이라고 알려줌
    return y

3. @overload (typing 모듈)

  • 함수나 메서드가 여러 가지 시그니처(입력 타입/개수)에 따라 다르게 동작할 수 있음을 타입 검사기에게 알려주는 데코레이터입니다.
  • 실제 구현은 마지막에 한 번만 작성하고, 그 위에 여러 개의 @overload 시그니처를 선언합니다.
  • 런타임에는 아무 영향이 없고, 타입 검사기만 참고합니다.
from typing import overload

@overload
def func(x: int) -> int: ...
@overload
def func(x: str) -> str: ...
def func(x):
    # 실제 구현
    if isinstance(x, int):
        return x + 1
    return x.upper()

4. Union[] (typing 모듈)

  • 여러 타입 중 하나가 올 수 있음을 명시합니다.
  • 예시: Union[int, str]는 int 또는 str 타입이 올 수 있음을 의미합니다.
from typing import Union

def foo(x: Union[int, str]):
    print(x)

5. Optional[] (typing 모듈)

  • 특정 타입 또는 None이 올 수 있음을 명시합니다.
  • Optional[X]Union[X, None]과 같습니다.
from typing import Optional

def foo(x: Optional[int]):
    if x is not None:
        print(x + 1)
    else:
        print("None!")

6. 실전 예시 (Hand4 생성자)

class Hand4:
    @overload
    def __init__(self, arg1: "Hand4") -> None: ...
    @overload
    def __init__(self, arg1: "Hand4", arg2: Card, *, split: int) -> None: ...
    @overload
    def __init__(self, arg1: Card, arg2: Card, arg3: Card) -> None: ...
    def __init__(self, arg1: Union["Hand4", Card], arg2: Optional[Card]=None, arg3: Optional[Card]=None, split: Optional[int]=None):
        # ...구현 생략...
  • 이렇게 여러 생성자 시그니처를 타입 검사기에 명확히 알려줄 수 있습니다.

7. 참고 자료

TIP: 타입 힌트와 타입 검사기는 코드의 안정성과 가독성을 높여주지만, 런타임 동작에는 영향을 주지 않습니다.
타입 힌트는 개발자와 도구(IDE, mypy 등)를 위한 정보입니다.
반응형
반응형
파이썬 map 함수 완벽 가이드

파이썬 map 함수 완벽 가이드

1. map 함수란?

  • map 함수는 반복 가능한 객체(리스트, 튜플 등)의 각 요소에 함수를 적용하여 새로운 이터레이터를 반환합니다.
  • 함수형 프로그래밍 스타일의 대표적인 내장 함수입니다.

2. 기본 문법

map(함수, 반복가능객체1[, 반복가능객체2, ...])
  • 여러 개의 반복가능객체를 동시에 처리할 수도 있습니다.
  • 결과는 이터레이터이므로, list() 등으로 감싸서 사용하거나 for문으로 순회해야 합니다.

3. 기본 예제

# 각 요소에 제곱 함수 적용
nums = [1, 2, 3, 4]
squares = map(lambda x: x ** 2, nums)
print(list(squares))  # [1, 4, 9, 16]

4. 여러 시퀀스 동시 처리

a = [1, 2, 3]
b = [10, 20, 30]
result = map(lambda x, y: x + y, a, b)
print(list(result))  # [11, 22, 33]

5. 자주 쓰이는 지원 함수/활용법

  • str, int, float 등 내장 함수와 함께 사용
str_nums = ['1', '2', '3']
nums = map(int, str_nums)
print(list(nums))  # [1, 2, 3]

words = ['hello', 'python']
upper_words = map(str.upper, words)
print(list(upper_words))  # ['HELLO', 'PYTHON']
  • filter, reduce와 조합
from functools import reduce
nums = [1, 2, 3, 4, 5]
squares = map(lambda x: x ** 2, nums)
even_squares = filter(lambda x: x % 2 == 0, squares)
sum_even = reduce(lambda x, y: x + y, even_squares)
print(sum_even)  # 20

6. map vs 리스트 컴프리헨션

  • 동일한 결과를 리스트 컴프리헨션으로도 얻을 수 있습니다.
nums = [1, 2, 3]
# map 사용
result1 = list(map(lambda x: x + 1, nums))
# 리스트 컴프리헨션 사용
result2 = [x + 1 for x in nums]
print(result1, result2)  # [2, 3, 4] [2, 3, 4]

7. map 객체의 특징

  • 게으른 평가(lazy evaluation): 실제로 값을 사용할 때만 함수가 적용됩니다.
  • 한 번 순회하면 소진됩니다(이터레이터).

8. map과 함께 자주 쓰는 내장 함수/패턴

  • list, tuple, set: map 결과를 원하는 컬렉션으로 변환
  • lambda: 간단한 함수를 즉석에서 정의
  • str, int, float, bool: 타입 변환에 자주 사용
  • operator 모듈: operator.add, operator.mul 등으로 더 간결하게
import operator
nums1 = [1, 2, 3]
nums2 = [4, 5, 6]
result = map(operator.mul, nums1, nums2)
print(list(result))  # [4, 10, 18]

9. map의 단점 및 주의점

  • 가독성이 떨어질 수 있음(특히 lambda가 복잡할 때)
  • 이터레이터이므로 여러 번 사용할 경우 list()로 변환 필요

10. 참고 자료

TIP: map은 대량 데이터 처리, 타입 변환, 여러 시퀀스 동시 처리 등에서 매우 유용합니다.
하지만 복잡한 로직에는 리스트 컴프리헨션이 더 가독성이 좋을 수 있습니다.
반응형
반응형
uv 패키지 관리 가이드

uv 패키지 관리 가이드

uv는 Python 프로젝트의 패키지 관리와 의존성 설치를 빠르고 효율적으로 도와주는 최신 패키지 매니저입니다.
공식 GitHub 저장소에서 최신 정보를 확인할 수 있습니다.

1. uv란?

  • Python용 초고속 패키지 관리 도구 (Rust로 구현)
  • pip, pip-tools, virtualenv, pipenv, poetry 등과 호환
  • 의존성 설치, 잠금(lock) 파일 생성, 가상환경 관리 등 지원

2. 설치 방법

curl -Ls https://astral.sh/uv/install.sh | sh
macOS, Linux, Windows 모두 지원합니다.

3. 주요 명령어

  • 패키지 설치:
    uv pip install 패키지명
    예시: uv pip install requests
  • 패키지 삭제:
    uv pip uninstall 패키지명
  • 패키지 목록 확인:
    uv pip list
  • requirements.txt 설치:
    uv pip install -r requirements.txt
  • 가상환경 생성:
    uv venv .venv
  • 가상환경 활성화:
    source .venv/bin/activate (macOS/Linux)
    .venv\Scripts\activate (Windows)
  • 패키지 업그레이드:
    uv pip install --upgrade 패키지명
  • 패키지 캐시 삭제:
    uv pip cache purge

4. 의존성 잠금(lock) 파일

  • lock 파일 생성:
    uv pip compile requirements.in
    requirements.txt 또는 requirements.lock 생성
  • lock 파일로 설치:
    uv pip sync requirements.txt

5. pip와의 차이점

  • 설치 속도가 매우 빠름 (Rust 기반)
  • pip, pip-tools, virtualenv, pipenv, poetry 등과 호환
  • 더 나은 캐싱 및 병렬 처리
  • pip 명령어와 거의 동일하게 사용 가능

6. 실전 예시

# 1. 가상환경 생성 및 활성화
uv venv .venv
source .venv/bin/activate

# 2. 패키지 설치
uv pip install numpy pandas

# 3. requirements.txt로부터 설치
uv pip install -r requirements.txt

# 4. lock 파일 생성 및 동기화
uv pip compile requirements.in
uv pip sync requirements.txt

# 5. 패키지 삭제
uv pip uninstall pandas
    

7. 참고 자료

TIP: uv는 기존 pip 프로젝트에도 바로 적용할 수 있습니다.
pip 대신 uv pip을 사용하면 더 빠르고 효율적인 패키지 관리를 경험할 수 있습니다.
반응형
반응형

Doctest 사용법

Python의 doctest 모듈은 소스 코드의 docstring에 포함된 예제 코드가 실제로 동작하는지 테스트할 수 있게 해줍니다. 아래는 doctest의 기본 사용법과 다양한 예시를 설명합니다.

1. doctest란?

doctest는 Python 표준 라이브러리로, 함수나 클래스의 docstring에 작성된 예제 코드(>>>로 시작하는 코드)를 실제로 실행하여 결과가 일치하는지 확인합니다.

2. 기본 사용법

예를 들어, 아래와 같이 함수의 docstring에 예제를 작성할 수 있습니다.

def add(a, b) :

def add(a, b):

"""

두 수를 더합니다.

>>> add(2, 3)

5

>>> add(-1, 1)

0

"""

return a + b

이제 doctest로 테스트를 실행할 수 있습니다.

python -m doctest your_module.py

3. 다양한 예시

예제 1: 리스트 뒤집기 함수

def reverse_list(lst) :

def reverse_list(lst):

"""

리스트를 뒤집어서 반환합니다.

>>> reverse_list([1, 2, 3])

[3, 2, 1]

>>> reverse_list([])

[]

"""

return lst[::-1]

**예제 2: 문자열 대문자 변환**def to_upper(s) :

def to_upper(s):

"""

문자열을 대문자로 변환합니다.

>>> to_upper('hello')

'HELLO'

>>> to_upper('Python')

'PYTHON'

"""

return s.upper()

**예제 3: 예외 발생 테스트**def divide(a, b) :

def divide(a, b):

"""

두 수를 나눕니다.

>>> divide(4, 2)

2.0

>>> divide(1, 0) # doctest: +IGNORE_EXCEPTION_DETAIL

Traceback (most recent call last):

ZeroDivisionError: division by zero

"""

return a / b

## 4. 모듈 전체 테스트하기 ##

파일 맨 아래에 아래 코드를 추가하면, 해당 파일을 직접 실행할 때 doctest가 자동으로 동작합니다.

if __name__ == "__main__" :

if __name__ == "__main__":

import doctest

doctest.testmod(verbose=True)

## 5. 여러 함수의 테스트 모음 ##

여러 함수의 테스트를 한 번에 모아서 실행할 수도 있습니다.

__test__ = {

__test__ = {

'add_test': """

>>> add(1, 2)

3

""",

'reverse_test': """

>>> reverse_list([1, 2])

[2, 1]

"""

}

## 6. doctest 옵션 ##

  • +ELLIPSIS: 일부 결과만 비교할 때 사용 (중간 생략 ...)
  • +IGNORE_EXCEPTION_DETAIL: 예외 메시지의 상세 내용 무시
  • +NORMALIZE_WHITESPACE: 공백 무시

예시:

def foo() :

def foo():

"""

>>> foo() # doctest: +ELLIPSIS

'result ...'

"""

return 'result with details'

## 7. 실전 예시: 카드 팩토리 함수 ##

아래는 ch02_ex3.py에서 사용된 카드 팩토리 함수의 doctest 예시입니다.

def card(rank, suit) :

def card(rank, suit):

"""

>>> deck = [card(rank, suit) for rank in range(1, 14) for suit in (Suit.Club, Suit.Diamond, Suit.Heart, Suit.Spade)]

>>> len(deck)

52

>>> sorted(set(c.suit for c in deck))

[, , , ]

>>> sorted(set(c.rank for c in deck))

['10', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'J', 'K', 'Q']

"""

# ...함수 구현...

## 8. 참고 ##

반응형

+ Recent posts