typing --- 類型標(biāo)注支持?
3.5 新版功能.
源碼: Lib/typing.py
注解
?Python 運(yùn)行時(shí)并不強(qiáng)制標(biāo)注函數(shù)和變量類型。類型標(biāo)注可被用于第三方工具,比如類型檢查器、集成開發(fā)環(huán)境、靜態(tài)檢查器等。
此模塊支持 PEP 484 和 PEP 526 指定的類型提示。最基本的支持由 Any,Union,Tuple,Callable,TypeVar 和 Generic 類型組成。有關(guān)完整的規(guī)范,請(qǐng)參閱 PEP 484。有關(guān)類型提示的簡(jiǎn)單介紹,請(qǐng)參閱 PEP 483。
函數(shù)接受并返回一個(gè)字符串,注釋像下面這樣:
def greeting(name: str) -> str:
return 'Hello ' + name
在函數(shù) greeting 中,參數(shù) name 預(yù)期是 str 類型,并且返回 str 類型。子類型允許作為參數(shù)。
類型別名?
類型別名通過將類型分配給別名來定義。在這個(gè)例子中, Vector 和 List[float] 將被視為可互換的同義詞:
from typing import List
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# typechecks; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
類型別名可用于簡(jiǎn)化復(fù)雜類型簽名。例如:
from typing import Dict, Tuple, Sequence
ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]
def broadcast_message(message: str, servers: Sequence[Server]) -> None:
...
# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
message: str,
servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
...
請(qǐng)注意,None 作為類型提示是一種特殊情況,并且由 type(None) 取代。
NewType?
使用 NewType() 輔助函數(shù)創(chuàng)建不同的類型:
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
靜態(tài)類型檢查器會(huì)將新類型視為它是原始類型的子類。這對(duì)于幫助捕捉邏輯錯(cuò)誤非常有用:
def get_user_name(user_id: UserId) -> str:
...
# typechecks
user_a = get_user_name(UserId(42351))
# does not typecheck; an int is not a UserId
user_b = get_user_name(-1)
您仍然可以對(duì) UserId 類型的變量執(zhí)行所有的 int 支持的操作,但結(jié)果將始終為 int 類型。這可以讓你在需要 int 的地方傳入 UserId,但會(huì)阻止你以無效的方式無意中創(chuàng)建 UserId:
# 'output' is of type 'int', not 'UserId'
output = UserId(23413) + UserId(54341)
注意,這些檢查只由靜態(tài)類型檢查器強(qiáng)制執(zhí)行。 在運(yùn)行時(shí),語句 Derived = NewType('Derived', Base) 將產(chǎn)生一個(gè) Derived 函數(shù),該函數(shù)立即返回你傳遞給它的任何參數(shù)。 這意味著表達(dá)式 Derived(some_value) 不會(huì)創(chuàng)建一個(gè)新的類,也不會(huì)引入超出常規(guī)函數(shù)調(diào)用的很多開銷。
更確切地說,表達(dá)式 some_value is Derived(some_value) 在運(yùn)行時(shí)總是為真。
這也意味著無法創(chuàng)建 Derived 的子類型,因?yàn)樗沁\(yùn)行時(shí)的標(biāo)識(shí)函數(shù),而不是實(shí)際的類型:
from typing import NewType
UserId = NewType('UserId', int)
# Fails at runtime and does not typecheck
class AdminUserId(UserId): pass
然而,我們可以在 "派生的" NewType 的基礎(chǔ)上創(chuàng)建一個(gè) NewType。
from typing import NewType
UserId = NewType('UserId', int)
ProUserId = NewType('ProUserId', UserId)
并且 ProUserId 的類型檢查將按預(yù)期工作。
有關(guān)更多詳細(xì)信息,請(qǐng)參閱 PEP 484。
注解
回想一下,使用類型別名聲明兩種類型彼此 等效 。Alias = Original 將使靜態(tài)類型檢查對(duì)待所有情況下 Alias 完全等同于 Original。當(dāng)您想簡(jiǎn)化復(fù)雜類型簽名時(shí),這很有用。
相反,NewType 聲明一種類型是另一種類型的子類型。Derived = NewType('Derived', Original) 將使靜態(tài)類型檢查器將 Derived 當(dāng)作 Original 的 子類 ,這意味著 Original 類型的值不能用于 Derived 類型的值需要的地方。當(dāng)您想以最小的運(yùn)行時(shí)間成本防止邏輯錯(cuò)誤時(shí),這非常有用。
3.5.2 新版功能.
Callable?
期望特定簽名的回調(diào)函數(shù)的框架可以將類型標(biāo)注為 Callable[[Arg1Type, Arg2Type], ReturnType]。
例如
from typing import Callable
def feeder(get_next_item: Callable[[], str]) -> None:
# Body
def async_query(on_success: Callable[[int], None],
on_error: Callable[[int, Exception], None]) -> None:
# Body
通過用文字省略號(hào)替換類型提示中的參數(shù)列表: Callable[...,ReturnType],可以聲明可調(diào)用的返回類型,而無需指定調(diào)用簽名。
泛型(Generic)?
由于無法以通用方式靜態(tài)推斷有關(guān)保存在容器中的對(duì)象的類型信息,因此抽象基類已擴(kuò)展為支持訂閱以表示容器元素的預(yù)期類型。
from typing import Mapping, Sequence
def notify_by_email(employees: Sequence[Employee],
overrides: Mapping[str, str]) -> None: ...
泛型可以通過使用typing模塊中名為 TypeVar 的新工廠進(jìn)行參數(shù)化。
from typing import Sequence, TypeVar
T = TypeVar('T') # Declare type variable
def first(l: Sequence[T]) -> T: # Generic function
return l[0]
用戶定義的泛型類型?
用戶定義的類可以定義為泛型類。
from typing import TypeVar, Generic
from logging import Logger
T = TypeVar('T')
class LoggedVar(Generic[T]):
def __init__(self, value: T, name: str, logger: Logger) -> None:
self.name = name
self.logger = logger
self.value = value
def set(self, new: T) -> None:
self.log('Set ' + repr(self.value))
self.value = new
def get(self) -> T:
self.log('Get ' + repr(self.value))
return self.value
def log(self, message: str) -> None:
self.logger.info('%s: %s', self.name, message)
Generic[T] 作為基類定義了類 LoggedVar 采用單個(gè)類型參數(shù) T。這也使得 T 作為類體內(nèi)的一個(gè)類型有效。
Generic 基類定義了 __class_getitem__() ,使得 LoggedVar[t] 作為類型有效:
from typing import Iterable
def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
for var in vars:
var.set(0)
泛型類型可以有任意數(shù)量的類型變量,并且類型變量可能會(huì)受到限制:
from typing import TypeVar, Generic
...
T = TypeVar('T')
S = TypeVar('S', int, str)
class StrangePair(Generic[T, S]):
...
Generic 每個(gè)參數(shù)的類型變量必須是不同的。這是無效的:
from typing import TypeVar, Generic
...
T = TypeVar('T')
class Pair(Generic[T, T]): # INVALID
...
您可以對(duì) Generic 使用多重繼承:
from typing import TypeVar, Generic, Sized
T = TypeVar('T')
class LinkedList(Sized, Generic[T]):
...
從泛型類繼承時(shí),某些類型變量可能是固定的:
from typing import TypeVar, Mapping
T = TypeVar('T')
class MyDict(Mapping[str, T]):
...
在這種情況下,MyDict 只有一個(gè)參數(shù),T。
在不指定類型參數(shù)的情況下使用泛型類別會(huì)為每個(gè)位置假設(shè) Any。在下面的例子中,MyIterable 不是泛型,但是隱式繼承自 Iterable[Any]:
from typing import Iterable
class MyIterable(Iterable): # Same as Iterable[Any]
用戶定義的通用類型別名也受支持。例子:
from typing import TypeVar, Iterable, Tuple, Union
S = TypeVar('S')
Response = Union[Iterable[S], int]
# Return type here is same as Union[Iterable[str], int]
def response(query: str) -> Response[str]:
...
T = TypeVar('T', int, float, complex)
Vec = Iterable[Tuple[T, T]]
def inproduct(v: Vec[T]) -> T: # Same as Iterable[Tuple[T, T]]
return sum(x*y for x, y in v)
在 3.7 版更改: Generic 不再擁有一個(gè)自定義的元類。
一個(gè)用戶定義的泛型類能夠使用抽象基本類作為基類,而不會(huì)發(fā)生元類沖突。泛型元類不再被支持。參數(shù)化泛型的結(jié)果會(huì)被緩存,并且在 typing 模塊中的大部分類型是可哈希且可比較相等性的。
Any 類型?
Any 是一種特殊的類型。靜態(tài)類型檢查器將所有類型視為與 Any 兼容,反之亦然, Any 也與所有類型相兼容。
這意味著可對(duì)類型為 Any 的值執(zhí)行任何操作或方法調(diào)用,并將其賦值給任何變量:
from typing import Any
a = None # type: Any
a = [] # OK
a = 2 # OK
s = '' # type: str
s = a # OK
def foo(item: Any) -> int:
# Typechecks; 'item' could be any type,
# and that type might have a 'bar' method
item.bar()
...
需要注意的是,將 Any 類型的值賦值給另一個(gè)更具體的類型時(shí),Python不會(huì)執(zhí)行類型檢查。例如,當(dāng)把 a 賦值給 s 時(shí),即使 s 被聲明為 str 類型,在運(yùn)行時(shí)接收到的是 int 值,靜態(tài)類型檢查器也不會(huì)報(bào)錯(cuò)。
此外,所有返回值無類型或形參無類型的函數(shù)將隱式地默認(rèn)使用 Any 類型:
def legacy_parser(text):
...
return data
# A static type checker will treat the above
# as having the same signature as:
def legacy_parser(text: Any) -> Any:
...
return data
當(dāng)需要混用動(dòng)態(tài)類型和靜態(tài)類型的代碼時(shí),上述行為可以讓 Any 被用作 應(yīng)急出口 。
Any 和 object 的行為對(duì)比。與 Any 相似,所有的類型都是 object 的子類型。然而不同于 Any,反之并不成立: object 不是 其他所有類型的子類型。
這意味著當(dāng)一個(gè)值的類型是 object 的時(shí)候,類型檢查器會(huì)拒絕對(duì)它的幾乎所有的操作。把它賦值給一個(gè)指定了類型的變量(或者當(dāng)作返回值)是一個(gè)類型錯(cuò)誤。比如說:
def hash_a(item: object) -> int:
# Fails; an object does not have a 'magic' method.
item.magic()
...
def hash_b(item: Any) -> int:
# Typechecks
item.magic()
...
# Typechecks, since ints and strs are subclasses of object
hash_a(42)
hash_a("foo")
# Typechecks, since Any is compatible with all types
hash_b(42)
hash_b("foo")
使用 object 示意一個(gè)值可以類型安全地兼容任何類型。使用 Any 示意一個(gè)值地類型是動(dòng)態(tài)定義的。
類,函數(shù)和修飾器.?
這個(gè)模塊定義了如下的類,模塊和修飾器.
-
class
typing.TypeVar? 類型變量
用法:
T = TypeVar('T') # Can be anything A = TypeVar('A', str, bytes) # Must be str or bytes
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function definitions. See class Generic for more information on generic types. Generic functions work as follows:
def repeat(x: T, n: int) -> Sequence[T]: """Return a list containing n references to x.""" return [x]*n def longest(x: A, y: A) -> A: """Return the longest of two strings.""" return x if len(x) >= len(y) else y
本質(zhì)上,后例的簽名重載了
(str, str) -> str與(bytes, bytes) -> bytes。注意,參數(shù)是str子類的實(shí)例時(shí),返回類型仍是純str。isinstance(x, T)會(huì)在運(yùn)行時(shí)拋出TypeError異常。一般地說,isinstance()和issubclass()不應(yīng)該和類型一起使用。通過
covariant=True或contravariant=True可以把類型變量標(biāo)記為協(xié)變量或逆變量。詳見 PEP 484。默認(rèn)情況下,類型變量是不變量。類型變量還可以用bound=<type>指定上限。這里的意思是,(顯式或隱式地)取代類型變量的實(shí)際類型必須是限定類型的子類,詳見 PEP 484。
-
class
typing.Generic? 用于泛型類型的抽象基類。
泛型類型一般通過繼承含一個(gè)或多個(gè)類型變量的類實(shí)例進(jìn)行聲明。例如,泛型映射類型定義如下:
class Mapping(Generic[KT, VT]): def __getitem__(self, key: KT) -> VT: ... # Etc.
這個(gè)類之后可以被這樣用:
X = TypeVar('X') Y = TypeVar('Y') def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y: try: return mapping[key] except KeyError: return default
-
class
typing.Type(Generic[CT_co])? 一個(gè)注解為
C的變量可以接受一個(gè)類型為C的值。相對(duì)地,一個(gè)注解為Type[C]的變量可以接受本身為類的值 —— 更精確地說它接受C的 類對(duì)象 ,例如:a = 3 # Has type 'int' b = int # Has type 'Type[int]' c = type(a) # Also has type 'Type[int]'
注意
Type[C]是協(xié)變的:class User: ... class BasicUser(User): ... class ProUser(User): ... class TeamUser(User): ... # Accepts User, BasicUser, ProUser, TeamUser, ... def make_new_user(user_class: Type[User]) -> User: # ... return user_class()
?
Type[C]是協(xié)變的這一事實(shí)暗示了任何C的子類應(yīng)當(dāng)實(shí)現(xiàn)與C相同的構(gòu)造器簽名和類方法簽名。類型檢查器應(yīng)當(dāng)標(biāo)記違反的情況,但應(yīng)當(dāng)也允許子類中調(diào)用構(gòu)造器符合指示的基類。類型檢查器被要求如何處理這種情況可能會(huì)在 PEP 484 將來的版本中改變。?
Type合法的參數(shù)僅有類、Any、類型變量 以及上述類型的聯(lián)合類型。例如:def new_non_team_user(user_class: Type[Union[BaseUser, ProUser]]): ...
?
Type[Any]等價(jià)于Type,因此繼而等價(jià)于type,它是 Python 的元類層級(jí)的根部。3.5.2 新版功能.
-
class
typing.Iterable(Generic[T_co])? collections.abc.Iterable的泛型版本。
-
class
typing.Iterator(Iterable[T_co])? collections.abc.Iterator的泛型版本。
-
class
typing.Reversible(Iterable[T_co])? collections.abc.Reversible的泛型版本。
-
class
typing.SupportsInt? 含抽象方法
__int__的抽象基類。
-
class
typing.SupportsFloat? 含抽象方法
__float__的抽象基類。
-
class
typing.SupportsComplex? 含抽象方法
__complex__的抽象基類。
-
class
typing.SupportsBytes? 含抽象方法
__bytes__的抽象基類(ABC)
-
class
typing.SupportsAbs? 含抽象方法
__abs__的抽象基類(ABC)是其返回類型里的協(xié)變量。
-
class
typing.SupportsRound? 含抽象方法
__round__的抽象基類,是其返回類型的協(xié)變量。
-
class
typing.Container(Generic[T_co])? collections.abc.Container的泛型版本。
-
class
typing.Hashable?
-
class
typing.Sized?
-
class
typing.Collection(Sized, Iterable[T_co], Container[T_co])? collections.abc.Collection的泛型版本。3.6.0 新版功能.
-
class
typing.AbstractSet(Sized, Collection[T_co])? collections.abc.Set的泛型版本。
-
class
typing.MutableSet(AbstractSet[T])? collections.abc.MutableSet的泛型版本。
-
class
typing.Mapping(Sized, Collection[KT], Generic[VT_co])? collections.abc.Mapping的泛型版本。這個(gè)類型可以如下使用:def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: return word_list[word]
-
class
typing.MutableMapping(Mapping[KT, VT])?
-
class
typing.Sequence(Reversible[T_co], Collection[T_co])? collections.abc.Sequence的泛型版本。
-
class
typing.MutableSequence(Sequence[T])?
-
class
typing.ByteString(Sequence[int])? collections.abc.ByteString的泛型版本。This type represents the types
bytes,bytearray, andmemoryview.作為該類型的簡(jiǎn)稱,
bytes可用于標(biāo)注上述任意類型的參數(shù)。
-
class
typing.Deque(deque, MutableSequence[T])? collections.deque的泛型版本。3.5.4 新版功能.
3.6.1 新版功能.
-
class
typing.List(list, MutableSequence[T])? list的泛型版本。適用于注解返回類型。注解參數(shù)時(shí),最好使用Sequence或Iterable等抽象容器類型。這個(gè)類型可以這樣用:
T = TypeVar('T', int, float) def vec2(x: T, y: T) -> List[T]: return [x, y] def keep_positives(vector: Sequence[T]) -> List[T]: return [item for item in vector if item > 0]
-
class
typing.Set(set, MutableSet[T])? builtins.set的泛型版本。適用于注解返回類型。注解參數(shù)時(shí),最好使用AbstractSet等抽象容器類型。
-
class
typing.FrozenSet(frozenset, AbstractSet[T_co])? builtins.frozenset的泛型版本。
-
class
typing.MappingView(Sized, Iterable[T_co])? collections.abc.MappingView的泛型版本。
-
class
typing.KeysView(MappingView[KT_co], AbstractSet[KT_co])? collections.abc.KeysView的泛型版本。
-
class
typing.ItemsView(MappingView, Generic[KT_co, VT_co])? collections.abc.ItemsView的泛型版本。
-
class
typing.ValuesView(MappingView[VT_co])? collections.abc.ValuesView的泛型版本。
-
class
typing.Awaitable(Generic[T_co])? collections.abc.Awaitable的泛型版本。3.5.2 新版功能.
-
class
typing.Coroutine(Awaitable[V_co], Generic[T_co T_contra, V_co])? collections.abc.Coroutine的泛型版本。類型變量的的差異和順序與Generator的內(nèi)容相對(duì)應(yīng),例如:from typing import List, Coroutine c = None # type: Coroutine[List[str], str, int] ... x = c.send('hi') # type: List[str] async def bar() -> None: x = await c # type: int
3.5.3 新版功能.
-
class
typing.AsyncIterable(Generic[T_co])? collections.abc.AsyncIterable的泛型版本。3.5.2 新版功能.
-
class
typing.AsyncIterator(AsyncIterable[T_co])? collections.abc.AsyncIterator的泛型版本。3.5.2 新版功能.
-
class
typing.ContextManager(Generic[T_co])? contextlib.AbstractContextManager的泛型版本。3.5.4 新版功能.
3.6.0 新版功能.
-
class
typing.AsyncContextManager(Generic[T_co])? contextlib.AbstractAsyncContextManager的泛型版本。3.5.4 新版功能.
3.6.2 新版功能.
-
class
typing.Dict(dict, MutableMapping[KT, VT])? dict的泛型版本。對(duì)標(biāo)注返回類型比較有用。如果要標(biāo)注參數(shù)的話,使用如Mapping的抽象容器類型是更好的選擇。這個(gè)類型可以這樣使用:
def count_words(text: str) -> Dict[str, int]: ...
-
class
typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])? collections.defaultdict的泛型版本。3.5.2 新版功能.
-
class
typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])? collections.OrderedDict的泛型版本。3.7.2 新版功能.
-
class
typing.Counter(collections.Counter, Dict[T, int])? collections.Counter的泛型版本。3.5.4 新版功能.
3.6.1 新版功能.
-
class
typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT])? collections.ChainMap的泛型版本。3.5.4 新版功能.
3.6.1 新版功能.
-
class
typing.Generator(Iterator[T_co], Generic[T_co, T_contra, V_co])? 生成器可以由泛型類型
Generator[YieldType, SendType, ReturnType]注解。例如:def echo_round() -> Generator[int, float, str]: sent = yield 0 while sent >= 0: sent = yield round(sent) return 'Done'
注意,與 typing 模塊里的其他泛型不同,
Generator的``SendType`` 的操作是逆變的, 不是協(xié)變,也是不變。如果生成器只生成值,可將
SendType與ReturnType設(shè)為None:def infinite_stream(start: int) -> Generator[int, None, None]: while True: yield start start += 1
另外,把生成器注解為返回類型
def infinite_stream(start: int) -> Iterator[int]: while True: yield start start += 1
-
class
typing.AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra])? 異步生成器可由泛型類型
AsyncGenerator[YieldType, SendType]注解。例如:async def echo_round() -> AsyncGenerator[int, float]: sent = yield 0 while sent >= 0.0: rounded = await round(sent) sent = yield rounded
與常規(guī)生成器不同,異步生成器不能返回值,因此沒有
ReturnType類型參數(shù)。 與Generator類似,SendType也屬于逆變行為。如果生成器只產(chǎn)生值,可將
SendType設(shè)置為None:async def infinite_stream(start: int) -> AsyncGenerator[int, None]: while True: yield start start = await increment(start)
此外,可用
AsyncIterable[YieldType]或AsyncIterator[YieldType]注解生成器的類型:async def infinite_stream(start: int) -> AsyncIterator[int]: while True: yield start start = await increment(start)
3.6.1 新版功能.
-
class
typing.Text? Text是str的別名。提供了對(duì) Python 2 代碼的向下兼容:Python 2 中,Text是``unicode`` 的別名。用
def add_unicode_checkmark(text: Text) -> Text: return text + u' \u2713'
3.5.2 新版功能.
-
class
typing.IO? -
class
typing.TextIO? -
class
typing.BinaryIO? 泛型類型
IO[AnyStr]及其子類TextIO(IO[str])與BinaryIO(IO[bytes])表示 I/O 流的類型,例如open()所返回的對(duì)象。
-
class
typing.Pattern? -
class
typing.Match? 這些類型對(duì)應(yīng)的是從
re.compile()和re.match()返回的類型。 這些類型(及相應(yīng)的函數(shù))是AnyStr中的泛型并可通過編寫Pattern[str],Pattern[bytes],Match[str]或Match[bytes]來具體指定。
-
class
typing.NamedTuple? collections.namedtuple()的類型版本。用法:
class Employee(NamedTuple): name: str id: int
這相當(dāng)于:
Employee = collections.namedtuple('Employee', ['name', 'id'])
為字段提供默認(rèn)值,要在類體內(nèi)賦值:
class Employee(NamedTuple): name: str id: int = 3 employee = Employee('Guido') assert employee.id == 3
帶默認(rèn)值的字段必須在不帶默認(rèn)值的字段后面。
The resulting class has two extra attributes:
_field_types, giving a dict mapping field names to types, and_field_defaults, a dict mapping field names to default values. (The field names are in the_fieldsattribute, which is part of the namedtuple API.)NamedTuple子類也支持文檔字符串與方法:class Employee(NamedTuple): """Represents an employee.""" name: str id: int = 3 def __repr__(self) -> str: return f'<Employee {self.name}, id={self.id}>'
反向兼容用法:
Employee = NamedTuple('Employee', [('name', str), ('id', int)])
在 3.6 版更改: 添加了對(duì) PEP 526 中變量注解句法的支持。
在 3.6.1 版更改: 添加了對(duì)默認(rèn)值、方法、文檔字符串的支持。
-
class
typing.ForwardRef? 用于字符串前向引用的內(nèi)部類型表示的類。 例如,
List["SomeClass"]會(huì)被隱式轉(zhuǎn)換為List[ForwardRef("SomeClass")]。 這個(gè)類不應(yīng)由用戶來實(shí)例化,但可以由內(nèi)省工具使用。
-
typing.NewType(typ)? A helper function to indicate a distinct types to a typechecker, see NewType. At runtime it returns a function that returns its argument. Usage:
UserId = NewType('UserId', int) first_user = UserId(1)
3.5.2 新版功能.
-
typing.cast(typ, val)? 把值強(qiáng)制轉(zhuǎn)換為類型。
不變更返回值。對(duì)類型檢查器來說,這代表了返回值具有指定的類型,但在運(yùn)行時(shí),故意不做任何檢查(目的是讓該檢查速度盡量快)。
-
typing.get_type_hints(obj[, globals[, locals]])? 返回一個(gè)字典,字典內(nèi)含有函數(shù)、方法、模塊或類對(duì)象的類型提示。
一般情況下,與
obj.__annotations__相同。此外,可通過在globals與locals命名空間里進(jìn)行評(píng)估,以此來處理編碼為字符串字面量的前向引用。如有需要,在默認(rèn)值設(shè)置為None``時(shí),可為函數(shù)或方法注解添加 ``Optional[t]。對(duì)于類C,則返回一個(gè)由所有__annotations__與C.__mro__逆序合并而成的字典。
-
@typing.overload? @overload裝飾器可以修飾支持多個(gè)不同參數(shù)類型組合的函數(shù)或方法。@overload- 裝飾定義的系列必須緊跟一個(gè)非@overload-裝飾定義(用于同一個(gè)函數(shù)/方法)。@overload-裝飾定義僅是為了協(xié)助類型檢查器, 因?yàn)樵撗b飾器會(huì)被非@overload-裝飾定義覆蓋,后者用于運(yùn)行時(shí),而且會(huì)被類型檢查器忽略。在運(yùn)行時(shí)直接調(diào)用@overload裝飾的函數(shù)會(huì)觸發(fā)NotImplementedError。下面的重載示例給出了比聯(lián)合類型或類型變量更精準(zhǔn)的類型:@overload def process(response: None) -> None: ... @overload def process(response: int) -> Tuple[int, str]: ... @overload def process(response: bytes) -> str: ... def process(response): <actual implementation>
詳見 PEP 484,與其他類型語義進(jìn)行對(duì)比。
-
@typing.no_type_check? 用于指明標(biāo)注不是類型提示的裝飾器。
此 decorator 裝飾器生效于類或函數(shù)上。如果作用于類上的話,它會(huì)遞歸地作用于這個(gè)類的所定義的所有方法上(但是對(duì)于超類或子類所定義的方法不會(huì)生效)。
此方法會(huì)就地地修改函數(shù)。
-
@typing.no_type_check_decorator? 使其它裝飾器起到
no_type_check()效果的裝飾器。本裝飾器用
no_type_check()里的裝飾函數(shù)打包其他裝飾器。
-
@typing.type_check_only? 標(biāo)記一個(gè)類或函數(shù)在運(yùn)行時(shí)內(nèi)不可用的裝飾器。
在運(yùn)行時(shí),該裝飾器本身不可用。實(shí)現(xiàn)返回了私有類實(shí)例時(shí),它主要是用于標(biāo)記在類型存根文件中定義的類。
@type_check_only class Response: # private or not available at runtime code: int def get_header(self, name: str) -> str: ... def fetch_response() -> Response: ...
注意,不建議返回私有類的實(shí)例,最好將這些類設(shè)為公共類。
-
typing.NoReturn? 標(biāo)記一個(gè)函數(shù)沒有返回值的特殊類型。比如說:
from typing import NoReturn def stop() -> NoReturn: raise RuntimeError('no way')
3.5.4 新版功能.
3.6.2 新版功能.
-
typing.Union? 聯(lián)合類型;
Union[X, Y]意味著:要不是 X,要不是 Y。使用形如
Union[int, str]的形式來定義一個(gè)聯(lián)合類型。細(xì)節(jié)如下:參數(shù)必須是類型,而且必須至少有一個(gè)參數(shù)。
聯(lián)合類型的聯(lián)合類型會(huì)被展開打平,比如:
Union[Union[int, str], float] == Union[int, str, float]
僅有一個(gè)參數(shù)的聯(lián)合類型會(huì)坍縮成參數(shù)自身,比如:
Union[int] == int # The constructor actually returns int
多余的參數(shù)會(huì)被跳過,比如:
Union[int, str, int] == Union[int, str]
在比較聯(lián)合類型的時(shí)候,參數(shù)順序會(huì)被忽略,比如:
Union[int, str] == Union[str, int]
你不能繼承或者實(shí)例化一個(gè)聯(lián)合類型。
你不能寫成
Union[X][Y]。你可以使用
Optional[X]作為Union[X, None]的縮寫。
在 3.7 版更改: 不要在運(yùn)行時(shí)內(nèi)從聯(lián)合類型中移除顯式說明的子類。
-
typing.Optional? 可選類型。
?
Optional[X]等價(jià)于Union[X, None]。請(qǐng)注意,這與可選參數(shù)并非相同的概念。可選參數(shù)是一個(gè)具有默認(rèn)值的參數(shù)。可選參數(shù)的類型注解并不因?yàn)樗强蛇x的就需要
Optional限定符。例如:def foo(arg: int = 0) -> None: ...
另一方面,如果允許顯式地傳遞值
None, 使用Optional也是正當(dāng)?shù)模瑹o論該參數(shù)是否是可選的。例如:def foo(arg: Optional[int] = None) -> None: ...
-
typing.Tuple? 元組類型;
Tuple[X, Y]標(biāo)注了一個(gè)二元組類型,其第一個(gè)元素的類型為 X 且第二個(gè)元素的類型為 Y。空元組的類型可寫作Tuple[()]。舉例:
Tuple[T1, T2]是一個(gè)二元組,類型分別為 T1 和 T2。Tuple[int, float, str]是一個(gè)由整數(shù)、浮點(diǎn)數(shù)和字符串組成的三元組。為表達(dá)一個(gè)同類型元素的變長(zhǎng)元組,使用省略號(hào)字面量,如
Tuple[int, ...]。單獨(dú)的一個(gè)Tuple等價(jià)于Tuple[Any, ...],進(jìn)而等價(jià)于tuple。
-
typing.Callable? 可調(diào)用類型;
Callable[[int], str]是一個(gè)函數(shù),接受一個(gè) int 參數(shù),返回一個(gè) str 。下標(biāo)值的語法必須恰為兩個(gè)值:參數(shù)列表和返回類型。參數(shù)列表必須是一個(gè)類型和省略號(hào)組成的列表;返回值必須是單一一個(gè)類型。
不存在語法來表示可選的或關(guān)鍵詞參數(shù),這類函數(shù)類型罕見用于回調(diào)函數(shù)。
Callable[..., ReturnType](使用字面省略號(hào))能被用于提示一個(gè)可調(diào)用對(duì)象,接受任意數(shù)量的參數(shù)并且返回ReturnType。單獨(dú)的Callable等價(jià)于Callable[..., Any],并且進(jìn)而等價(jià)于collections.abc.Callable。
-
typing.ClassVar? 特殊的類型構(gòu)造器,用以標(biāo)記類變量。
在 PEP 526 中被引入,ClassVar 包裹起來的變量注解指示了給定屬性預(yù)期用于類變量,并且不應(yīng)在類的實(shí)例上被設(shè)置。用法:
class Starship: stats: ClassVar[Dict[str, int]] = {} # class variable damage: int = 10 # instance variable
ClassVar僅接受類型,并且不能被再次下標(biāo)。ClassVar本身并不是一個(gè)類,并且不應(yīng)與isinstance()orissubclass()一起使用。ClassVar并不改變 Python 運(yùn)行時(shí)行為,但它可以被用于第三方類型檢查器。例如,某個(gè)類型檢查器可能會(huì)標(biāo)記以下代碼為錯(cuò)誤的:enterprise_d = Starship(3000) enterprise_d.stats = {} # Error, setting class variable on instance Starship.stats = {} # This is OK
3.5.3 新版功能.
-
typing.AnyStr? AnyStr類型變量的定義為AnyStr = TypeVar('AnyStr', str, bytes)。這里指的是,它可以接受任意同類字符串,但不支持混用不同類別的字符串。例如:
def concat(a: AnyStr, b: AnyStr) -> AnyStr: return a + b concat(u"foo", u"bar") # Ok, output has type 'unicode' concat(b"foo", b"bar") # Ok, output has type 'bytes' concat(u"foo", b"bar") # Error, cannot mix unicode and bytes
-
typing.TYPE_CHECKING? 被第三方靜態(tài)類型檢查器假定為
True的特殊常量。 在運(yùn)行時(shí)為False。 用法如下:if TYPE_CHECKING: import expensive_mod def fun(arg: 'expensive_mod.SomeType') -> None: local_var: expensive_mod.AnotherType = other_fun()
Note that the first type annotation must be enclosed in quotes, making it a "forward reference", to hide the
expensive_modreference from the interpreter runtime. Type annotations for local variables are not evaluated, so the second annotation does not need to be enclosed in quotes.3.5.2 新版功能.
