$ python3 -m mypy --strict example.pydef subtract(a: int, b:int) -> int:
return a-b
subtract(10, '5')
$ python3 -m mypy --strict example.py
.../example.py: error: Argument 2 to "subtract" has incompatible type "str"; expected "int"
class Counter:
def __init__(self) -> None:
self.value: int = 0 # 필드/변수 annotation
def add(self, offset: int) -> None:
value += offset # 헉. 'self.'를 안썼다..
def get(self) -> int:
self.value # 헉. 'return'을 안썼다..
counter = Counter()
counter.add(5)
counter.add(3)
assert counter.get() == 8
$ python3 -m mypy --strict example.py
.../example.py:6: error: Name 'value' is not defined
.../example.py:8: error: Missing return statement
from typing import Callable, List, TypeVar
Value = TypeVar('Value') # Can be anything
Func = Callable[[Value, Value], Value]
def combine(func: Func[Value], values: List[Value]) -> Value:
assert len(values) > 0
result = values[0]
for next_value in values[1:]:
result = func(result, next_value)
return result
Real = TypeVar('Real', int, float)
def add(x: Real, y: Real) -> Real:
return x + y
inputs = [1, 2, 3, 4j]
result = combine(add, inputs)
assert result == 10
$ python3 -m mypy --strict example.py
.../example.py:21: error: Argument 1 to "combine" has incompatible type "Callable[[Real, Real], Real]"; expected "Callable[[complex, complex], complex]"
Typing 사용법typing.Type 사용법typing.TypeVar 사용법TypeVar는 제네릭 타입을 만들 때 사용하는 클래스입니다.
제네릭 타입?
제네릭 타입은 클래스나 함수에서 사용할 데이터 타입을 나중에 지정할 수 있는 타입입니다.
제네릭 타입을 사용하면 데이터 타입에 대한 추상화 수준을 높일 수 있으며, 코드 재사용성과 유연성을 높일 수 있습니다.
제네릭 타입은 다음과 같은 장점을 가집니다.
제네릭 타입은 다양한 프로그래밍 언어에서 지원됩니다.
Python에서도 제네릭 타입을 지원하며, typing 모듈을 사용하여 제네릭 함수나 클래스를 정의할 수 있습니다.
예를 들어, List, Tuple, Dict 등은 제네릭 타입으로 정의되어 있으며, 다양한 데이터 타입의 요소를 저장할 수 있습니다.
TypeVar를 사용하면 타입 어노테이션에서
TypeVar 클래스를 사용하는 방법은 다음과 같습니다.
from typing import TypeVar
T = TypeVar('T') # Can be anything
S = TypeVar('S', bound=str) # Can be any subtype of str
A = TypeVar('A', str, bytes) # Must be exactly str or bytes
U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes
# SupportsAbs -> abstract types (ABCs or protocols)
V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method
typing.Callable 사용법Callable[[int], str] is a function of (int) -> str....Callable[..., ReturnType]은 범용적으로 쓰일 수 있다.Callable = Callable[..., Any] = collections.abc.Callabletyping.Optional 사용법typing.Optinal[X] == typing.Union[X, None]from typing import Optional
def get_or_default(value: Optional[int], default: int) -> int:
if value is not None:
return value
return default
typing.Union 사용법typing.Union[X, Y] == X|Y(얜 파이썬 3.10부터 사용가능 ㅠ)collections.abc 사용법collections.abc.Mappingcollections.abc.Mapping or collections.abc.MutableMapping abstract base classes. dict, collections.defaultdict, collections.OrderedDict and collections.Counter.from collections.abc import Mapping, Sequence
from typing import Any
def keys(mapping: Mapping[str, Any]) -> Sequence[str]:
return tuple(mapping)
collections.abc.SequenceAn iterable which supports efficient element access using integer indices via the __getitem__() special method and defines a __len__() method that returns the length of the sequence.
Some built-in sequence types are list, str, tuple, and bytes.
Note that dict also supports __getitem__() and __len__(), but is considered a mapping rather than a sequence because the lookups use arbitrary immutable keys rather than integers.
The collections.abc.Sequence abstract base class defines a much richer interface that goes beyond just __getitem__() and __len__(), adding count(), index(), __contains__(), and __reversed__().
Types that implement this expanded interface can be registered explicitly using register().
collections.abc.Callable__call__() method.from collections.abc import Callable
def instantiate(factory: Callable[[], int]) -> int:
return factory()
NameError: name `SecondClass` is not definedclass FirstClass:
def __init__(self, value: 'SecondClass') -> None:
self.value = value
from __future__ import annotations
# 프로그램 실행 시, type annotation 에 지정된 값을 완전히 무시하라고 지시한다.
class FirstClass:
def __init__(self, value: SecondClass) -> None:
self.value = value