typing使用

忞翛發表於2021-11-17

官方文件: typing
注: typing是python3.5(PEP484)開始的
可用於: 型別檢查器、整合開發環境、靜態檢查器等, 但是不強制使用

使用方式

兩種使用方式

  1. 別名: 先定義=, 再使用:
  2. 直接使用: :
from typing import List

T1 = List[str]


def test(t1: T1, t2: List[str]):
    print(t1[0].title())
    print(t2[0].title())

建立新型別 NewType

主要用於型別檢測
NewType(name, tp) 返回其原本的值
靜態型別檢查器會將新型別看作是原始型別的一個子類
即: name是新的型別 tp是原始型別
注: 在python3.10之前NewType是普通的函式, 之後是一個類, 會產生一個類, 返回的原來的值, 故不會對常規函式產生影響

from typing import NewType, NoReturn

# 建立int的子類, 名為UserId
UserIdType = NewType('UserId', int)


# 使用
def name_by_id(user_id: UserIdType) -> NoReturn:
    print(user_id)


# 型別檢測錯誤
UserIdType('user')

# 型別檢測成功, 返回原型別 "int"
num = UserIdType(5)

# 型別檢測錯誤, 需要傳入UserIdType, 而不是int
name_by_id(42)
# 型別檢測成功
name_by_id(UserIdType(42))  # OK

型別變數 TypeVar

型別變數主要用於泛型型別與泛型函式定義的引數
第一個引數是名稱, 其他引數是型別

from typing import TypeVar, Sequence

# 任意型別
T = TypeVar('T')
# 必須是str或bytes
A = TypeVar('A', str, bytes)


# (any, int) -> [any, ...]
def repeat(x: T, n: int) -> Sequence[T]:
    return [x] * n


# (str/bytes, str/bytes) -> str/bytes
def longest(x: A, y: A) -> A:
    return x if len(x) >= len(y) else y

元祖 Tuple

使用場景

  1. 有限元素: Tuple[X, Y], 即第一個元素型別為X, 第二個元素型別為Y
  2. 空元組: Tuple[()]
  3. 可用...指定任意個同類: Tuple[int, ...]即多個int元素的元組
  4. 不指定時(Tuple)等價於Tuple[Any, ...]
from typing import Tuple


# 任意型別元組
def t1(t: Tuple):
    pass


# 全為字串的元組
def t2(t: Tuple[str, ...]):
    pass


# 多個型別有 "..." 時為任意型別
def t3(t: Tuple[str, int, ...]):
    pass

列表 List

使用方式如上的Tuple

from typing import List


# 任意型別
def t1(t: List):
    pass


# 全為字串
def t2(t: List[str, ...]):
    pass


# 多個型別有 "..." 時為任意型別
def t3(t: List[str, int, ...]):
    pass

字典 Dict

定義形式: Dict[key型別, val型別]

from typing import Dict


# key為字串 value為int
def t1(t: Dict[str, int]):
    pass
	

集合 Set

不能使用...
最多隻能有一個引數, 即只能有一種型別

from typing import Set


# 任意型別
def t1(t: Set):
    pass


# 字串
def t2(t: Set[str]):
    pass

序列型別 Sequence

使用注意點與Set相同

from typing import Union, Sequence


# int
def t1(t: Sequence[int]):
    pass

可呼叫型別 Callable

即可呼叫物件
定義形如: Callable[[Arg1Type, Arg2Type], ReturnType], 第一個引數是列表 值為可呼叫物件的引數型別, 第二個引數是返回值

from typing import Callable


def test(c: Callable[[int, str], str]):
    res = c(1, "a")
    # 1a <class 'str'>
    print(res, type(res))


def func(a: int, b: str) -> str:
    return str(a) + b


test(func)

任意型別 Any

任意型別

from typing import Any


# 任意型別
def t1(a: Any, b: ...):
    pass


t1(1, 2)
t1("a", "b")

無返回值 NoReturn

標記沒有返回值的函式

from typing import NoReturn

def stop() -> NoReturn:
    raise RuntimeError('no way')
	

聯合型別 Union

即必須是指定的型別

聯合中的聯合會被展平: Union[Union[int, str], float] == Union[int, str, float]
單引數即本身: Union[int] == int
冗餘引數跳過: Union[int, str, int] == Union[int, str] == int | str
無順序: Union[int, str] == Union[str, int]

from typing import Union


# str或int
def t1(t: Union[str, int]):
    pass

python3.10之後可以寫成X | Y, 不需要額外匯入Union

可選型別 Optional

即可以是指定的型別

含預設值的可選引數不需要在型別註解上新增 Optional 限定符
預設值為None時, 可以用Optional

from typing import Optional


# t的型別可以是int
def t1(t: Optional[int] = None):
    pass

相關文章