On this page
键入-支持类型提示
3.5 版中的新Function。
源代码: Lib/typing.py
Note
Python 运行时不强制执行函数和变量类型 Comments。它们可以被第三方工具(例如类型检查器,IDE,短毛绒等)使用。
此模块为 PEP 484, PEP 526, PEP 544, PEP 586, PEP 589和 PEP 591指定的类型提示提供运行时支持。最基本的支持包括类型Any,Union,Tuple,Callable,TypeVar和Generic。有关完整规范,请参见 PEP 484。有关类型提示的简化介绍,请参见 PEP 483。
下面的函数接受并返回一个字符串,其 Comments 如下:
def greeting(name: str) -> str:
return 'Hello ' + name
在函数greeting
中,参数name
的类型应为str,返回类型为str。子类型被接受为参数。
Type aliases
pass将类型分配给别名来定义类型别名。在此示例中,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])
类型别名对于简化复杂的类型签名很有用。例如:
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:
...
请注意,None
作为类型提示是一种特殊情况,并由type(None)
代替。
NewType
使用NewType()辅助函数创建不同的类型:
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
静态类型检查器会将新类型视为原始类型的子类。这有助于帮助捕获逻辑错误:
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)
您仍然可以对UserId
类型的变量执行所有int
操作,但结果始终为int
类型。这使您可以在可能需要int
的地方传递UserId
,但可以防止您以无效的方式意外创建UserId
:
# 'output' is of type 'int', not 'UserId'
output = UserId(23413) + UserId(54341)
请注意,这些检查仅由静态类型检查器强制执行。在运行时,语句Derived = NewType('Derived', Base)
将使Derived
一个函数,该函数立即返回您传递给它的任何参数。这意味着表达式Derived(some_value)
不会创建新类或引入任何常规函数调用之外的开销。
更准确地说,表达式some_value is Derived(some_value)
在运行时始终为 true。
这也意味着不可能创建Derived
的子类型,因为它是运行时的标识函数,而不是实际的类型:
from typing import NewType
UserId = NewType('UserId', int)
# Fails at runtime and does not typecheck
class AdminUserId(UserId): pass
但是,可以基于“派生的” NewType
创建一个NewType():
from typing import NewType
UserId = NewType('UserId', int)
ProUserId = NewType('ProUserId', UserId)
并按预期检查ProUserId
的类型。
有关更多详细信息,请参见 PEP 484。
Note
回想一下,使用类型别名语句两种类型彼此“等效”。在所有情况下,执行Alias = Original
都会使静态类型检查器将Alias
等同于Original
。当您要简化复杂的类型签名时,这很有用。
相反,NewType
语句一种类型为另一种的子类型。进行Derived = NewType('Derived', Original)
会使静态类型检查器将Derived
视为Original
的子类,这意味着Original
类型的值不能在预期值为Derived
类型的地方使用。当您希望以最小的运行时成本来防止逻辑错误时,这很有用。
版本 3.5.2 中的新Function。
Callable
期望使用特定签名的回调函数的框架可以使用Callable[[Arg1Type, Arg2Type], ReturnType]
进行类型提示。
For example:
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
pass用 Literals Ellipsis号代替类型提示中的参数列表Callable[..., ReturnType]
,可以语句可调用的返回类型而无需指定调用签名。
Generics
由于无法以通用方式静态推断有关保存在容器中的对象的类型信息,因此对抽象 Base Class 进行了扩展以支持预订,以表示容器元素的预期类型。
from typing import Mapping, Sequence
def notify_by_email(employees: Sequence[Employee],
overrides: Mapping[str, str]) -> None: ...
泛型可以pass使用一个新的工厂来进行参数化,该工厂可以键入TypeVar。
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]
作为 Base Class 定义了LoggedVar
类采用单个类型参数T
。这也使T
作为类体内的类型有效。
GenericBase Class 定义class_getitem(),因此LoggedVar[t]
作为类型有效:
from typing import Iterable
def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
for var in vars:
var.set(0)
泛型类型可以具有任意数量的类型变量,并且类型变量可能受到约束:
from typing import TypeVar, Generic
...
T = TypeVar('T')
S = TypeVar('S', int, str)
class StrangePair(Generic[T, S]):
...
Generic的每个类型变量参数都必须是不同的。因此,这是无效的:
from typing import TypeVar, Generic
...
T = TypeVar('T')
class Pair(Generic[T, T]): # INVALID
...
您可以对Generic使用多重继承:
from typing import TypeVar, Generic, Sized
T = TypeVar('T')
class LinkedList(Sized, Generic[T]):
...
从泛型类继承时,可以修复某些类型变量:
from typing import TypeVar, Mapping
T = TypeVar('T')
class MyDict(Mapping[str, T]):
...
在这种情况下,MyDict
具有单个参数T
。
在不指定类型参数的情况下使用泛型类,则假定每个位置为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不再具有自定义元类。
用户定义的泛型类可以将 ABC 作为 Base Class 而不会出现元类冲突。不支持通用元类。参数化泛型的结果将被缓存,并且键入模块中的大多数类型都是可哈希化的,并且具有相等性。
任何类型
特殊类型是Any。静态类型检查器会将每种类型都视为与Any和Any兼容,从而认为每种类型都兼容。
这意味着可以对Any类型的值执行任何操作或方法调用,并将其分配给任何变量:
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的值分配给更精确的类型时,不会执行类型检查。例如,即使将s
语句为str类型并在运行时收到int值,将a
分配给s
时,静态类型检查器也不会报告错误!
此外,所有没有返回类型或参数类型的函数都将默认使用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
当您需要混合使用动态和静态类型的代码时,此行为允许Any用作“逃生 shade”。
将Any的行为与object的行为进行对比。与Any相似,每种类型都是object的子类型。但是,与Any不同的是,情况并非如此:object不是所有其他类型的子类型。
这意味着,当值的类型为object时,类型检查器将拒绝对其执行的几乎所有操作,并将其分配给更专门类型的变量(或将其用作返回值)是类型错误。例如:
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以类型安全的方式指示值可以是任何类型。使用Any指示值是动态键入的。
标称与结构子类型
最初 PEP 484使用* nominal subtyping *定义了 Python 静态类型系统。这意味着,当且仅当A
是B
的子类时,才允许A
类。
以前,此要求还适用于抽象 Base Class,例如Iterable。这种方法的问题在于必须显式地标记一个类以支持它们,这是非 Python 的,并且不同于惯用的动态类型化 Python 代码通常会执行的操作。例如,这符合 PEP 484:
from typing import Sized, Iterable, Iterator
class Bucket(Sized, Iterable[int]):
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
PEP 544pass允许用户编写上述代码而无需在类定义中使用显式 Base Class 来解决此问题,并允许Bucket
被静态类型检查器隐式视为Sized
和Iterable[int]
的子类型。这称为结构子类型(或静态鸭子类型):
from typing import Iterator, Iterable
class Bucket: # Note: no base classes
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket()) # Passes type check
此外,pass将特殊类Protocol子类化,用户可以定义新的自定义协议以充分享受结构性子类型化(请参见下面的示例)。
类,函数和装饰器
该模块定义了以下类,函数和装饰器:
- 类别
typing.
TypeVar
- Type variable.
Usage:
T = TypeVar('T') # Can be anything
A = TypeVar('A', str, bytes) # Must be str or bytes
类型变量的存在主要是为了使静态类型检查器受益。它们用作通用类型以及通用函数定义的参数。有关泛型类型的更多信息,请参见类 Generic。通用函数的工作方式如下:
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
后一个示例的签名实质上是(str, str) -> str
和(bytes, bytes) -> bytes
的重载。还要注意,如果参数是str的某些子类的实例,则返回类型仍然是str。
在运行时,isinstance(x, T)
将提高TypeError。通常,isinstance()和issubclass()不应与类型一起使用。
pass传递covariant=True
或contravariant=True
可以将类型变量标记为协变或逆变。有关更多详细信息,请参见 PEP 484。默认情况下,类型变量是不变的。或者,类型变量可以使用bound=<type>
指定上限。这意味着(用显式或隐式)替换类型变量的实际类型必须是边界类型的子类,请参见 PEP 484。
- 类别
typing.
Generic
- 泛型类型的抽象 Base Class。
通常pass从具有一个或多个类型变量的此类实例化实例中继承来语句泛型类型。例如,通用 Map 类型可以定义为:
class Mapping(Generic[KT, VT]):
def __getitem__(self, key: KT) -> VT:
...
# Etc.
然后可以按如下方式使用此类:
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
- 类别
typing.
Protocol
(通用)- 协议类的 Base Class。协议类的定义如下:
class Proto(Protocol):
def meth(self) -> int:
...
这些类主要与识别结构子类型(静态鸭子类型)的静态类型检查器一起使用,例如:
class C:
def meth(self) -> int:
return 0
def func(x: Proto) -> int:
return x.meth()
func(C()) # Passes static type check
有关详情,请参见 PEP 544。用runtime_checkable()装饰的协议类(稍后描述)充当头脑简单的运行时协议,该协议仅检查给定属性的存在,而忽略它们的类型签名。
协议类可以是通用的,例如:
class GenProto(Protocol[T]):
def meth(self) -> T:
...
3.8 版的新Function。
-
- class *
typing.
Type
(* Generic [CT_co] *)
- 带有
C
Comments 的变量可以接受C
类型的值。相反,带有Type[C]
Comments 的变量可以接受本身就是类的值-具体来说,它将接受C
的* class object *。例如:
- class *
a = 3 # Has type 'int'
b = int # Has type 'Type[int]'
c = type(a) # Also has type 'Type[int]'
请注意,Type[C]
是协变的:
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]
是协变的事实意味着C
的所有子类都应实现与C
相同的构造函数签名和类方法签名。类型检查器应标记对此行为的违反,但也应允许子类中的构造函数调用与指示的 Base Class 中的构造函数调用匹配。在将来的 PEP 484修订版中,可能需要更改类型检查器的方式才能进行处理。
Type的唯一合法参数是类Any,type variables和任何这些类型的联合。例如:
def new_non_team_user(user_class: Type[Union[BaseUser, ProUser]]): ...
Type[Any]
等效于Type
,而Type
等效于type
,后者是 Python 元类层次结构的根。
版本 3.5.2 中的新Function。
-
- class *
typing.
Iterable
(* Generic [T_co] *)
- collections.abc.Iterable的通用版本。
- class *
-
- class *
typing.
Iterator
(* Iterable [T_co] *)
- collections.abc.Iterator的通用版本。
- class *
-
- class *
typing.
Reversible
(* Iterable [T_co] *)
- class *
类别
typing.
SupportsInt
- 具有一种抽象方法
__int__
的 ABC。
- 具有一种抽象方法
类别
typing.
SupportsFloat
- 具有一种抽象方法
__float__
的 ABC。
- 具有一种抽象方法
类别
typing.
SupportsComplex
- 具有一种抽象方法
__complex__
的 ABC。
- 具有一种抽象方法
类别
typing.
SupportsBytes
- 具有一种抽象方法
__bytes__
的 ABC。
- 具有一种抽象方法
类别
typing.
SupportsIndex
- 具有一种抽象方法
__index__
的 ABC。
- 具有一种抽象方法
3.8 版的新Function。
类别
typing.
SupportsAbs
- 具有一个抽象方法
__abs__
的 ABC,其返回类型是协变的。
- 具有一个抽象方法
类别
typing.
SupportsRound
- 具有一个抽象方法
__round__
的 ABC,其返回类型是协变的。
- 具有一个抽象方法
-
- class *
typing.
Container
(* Generic [T_co] *)
- class *
类别
typing.
Hashable
类别
typing.
Sized
类别
typing.
Collection
(*大小,可迭代[T_co],容器[T_co] *)
3.6.0 版中的新Function。
-
- class *
typing.
AbstractSet
(* Sized,Collection [T_co] *)
- collections.abc.Set的通用版本。
- class *
-
- class *
typing.
MutableSet
(* AbstractSet [T] *)
- class *
类别
typing.
Mapping
(*大小,集合[KT],通用[VT_co] *)- collections.abc.Mapping的通用版本。此类型可以如下使用:
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
(*可逆[T_co],集合[T_co] *)- collections.abc.Sequence的通用版本。
类别
typing.
MutableSequence
(*序列[T] *)-
- class *
typing.
ByteString
(* Sequence [int] *)
- class *
此类型表示字节序列的类型bytes,bytearray和memoryview。
作为此类型的简写,bytes可用于 Comments 上述任何类型的参数。
-
- class *
typing.
Deque
(* deque,MutableSequence [T] *)
- collections.deque的通用版本。
- class *
3.5.4 版中的新Function。
版本 3.6.1 中的新Function。
-
- class *
typing.
List
(* list,MutableSequence [T] *)
- class *
此类型可以按如下方式使用:
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的通用版本。用于 Comments 返回类型。要 Comments 参数,最好使用抽象集合类型,例如AbstractSet。
- class *
-
- class *
typing.
FrozenSet
(* frozenset,AbstractSet [T_co] *)
- builtins.frozenset的通用版本。
- class *
类别
typing.
MappingView
(*大小,可迭代[T_co] *)-
- class *
typing.
KeysView
(* MappingView [KT_co],AbstractSet [KT_co] *)
- collections.abc.KeysView的通用版本。
- class *
-
- class *
typing.
ItemsView
(* MappingView,Generic [KT_co,VT_co] *)
- class *
-
- class *
typing.
ValuesView
(* MappingView [VT_co] *)
- class *
-
- class *
typing.
Awaitable
(* Generic [T_co] *)
- class *
版本 3.5.2 中的新Function。
-
- class *
typing.
Coroutine
(* Awaitable [V_co],Generic [T_co T_contra,V_co] *)
- collections.abc.Coroutine的通用版本。类型变量的方差和 Sequences 与Generator的方差和 Sequences 相对应,例如:
- class *
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 中的新Function。
-
- class *
typing.
AsyncIterable
(* Generic [T_co] *)
- class *
版本 3.5.2 中的新Function。
-
- class *
typing.
AsyncIterator
(* AsyncIterable [T_co] *)
- class *
版本 3.5.2 中的新Function。
-
- class *
typing.
ContextManager
(* Generic [T_co] *)
- class *
3.5.4 版中的新Function。
3.6.0 版中的新Function。
-
- class *
typing.
AsyncContextManager
(* Generic [T_co] *)
- class *
3.5.4 版中的新Function。
版本 3.6.2 中的新Function。
-
- class *
typing.
Dict
(* dict,MutableMapping [KT,VT] *)
- class *
此类型可以如下使用:
def count_words(text: str) -> Dict[str, int]:
...
-
- class *
typing.
DefaultDict
(* collections.defaultdict,MutableMapping [KT,VT] *)
- collections.defaultdict的通用版本。
- class *
版本 3.5.2 中的新Function。
-
- class *
typing.
OrderedDict
(* collections.OrderedDict,MutableMapping [KT,VT] *)
- collections.OrderedDict的通用版本。
- class *
3.7.2 版中的新Function。
-
- class *
typing.
Counter
(* collections.Counter,Dict [T,int] *)
- collections.Counter的通用版本。
- class *
3.5.4 版中的新Function。
版本 3.6.1 中的新Function。
-
- class *
typing.
ChainMap
(* collections.ChainMap,MutableMapping [KT,VT] *)
- collections.ChainMap的通用版本。
- class *
3.5.4 版中的新Function。
版本 3.6.1 中的新Function。
-
- class *
typing.
Generator
(* Iterator [T_co],Generic [T_co,T_contra,V_co] *)
- 生成器可以用通用类型
Generator[YieldType, SendType, ReturnType]
Comments。例如:
- class *
def echo_round() -> Generator[int, float, str]:
sent = yield 0
while sent >= 0:
sent = yield round(sent)
return 'Done'
请注意,与类型模块中的许多其他泛型不同,Generator的SendType
的行为是相反的,而不是协变的或不变的。
如果您的生成器仅产生值,请将SendType
和ReturnType
设置为None
:
def infinite_stream(start: int) -> Generator[int, None, None]:
while True:
yield start
start += 1
或者,将生成器 Comments 为返回类型为Iterable[YieldType]
或Iterator[YieldType]
:
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]
Comments 异步生成器。例如:
- class *
async def echo_round() -> AsyncGenerator[int, float]:
sent = yield 0
while sent >= 0.0:
rounded = await round(sent)
sent = yield rounded
与普通生成器不同,异步生成器无法返回值,因此没有ReturnType
类型参数。与Generator一样,SendType
的行为相反。
如果您的生成器仅产生值,请将SendType
设置为None
:
async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
while True:
yield start
start = await increment(start)
或者,将生成器 Comments 为返回类型为AsyncIterable[YieldType]
或AsyncIterator[YieldType]
:
async def infinite_stream(start: int) -> AsyncIterator[int]:
while True:
yield start
start = await increment(start)
版本 3.6.1 中的新Function。
- 类别
typing.
Text
Text
是str
的别名。提供它是为了提供 Python 2 代码的前向兼容路径:在 Python 2 中,Text
是unicode
的别名。
使用Text
表示值必须包含与 Python 2 和 Python 3 兼容的 unicode 字符串:
def add_unicode_checkmark(text: Text) -> Text:
return text + u' \u2713'
版本 3.5.2 中的新Function。
类别
typing.
IO
类别
typing.
TextIO
类别
typing.
BinaryIO
- 通用类型
IO[AnyStr]
及其子类TextIO(IO[str])
和BinaryIO(IO[bytes])
表示 I/O 流的类型,例如open()返回。
- 通用类型
类别
typing.
Pattern
类别
typing.
Match
- 这些类型别名对应于re.compile()和re.match()的返回类型。这些类型(以及相应的Function)在
AnyStr
中是通用的,可以pass写入Pattern[str]
,Pattern[bytes]
,Match[str]
或Match[bytes]
加以特定。
- 这些类型别名对应于re.compile()和re.match()的返回类型。这些类型(以及相应的Function)在
类别
typing.
NamedTuple
- collections.namedtuple()的 Importing 版本。
Usage:
class Employee(NamedTuple):
name: str
id: int
这等效于:
Employee = collections.namedtuple('Employee', ['name', 'id'])
要为字段提供默认值,您可以在类主体中为其指定:
class Employee(NamedTuple):
name: str
id: int = 3
employee = Employee('Guido')
assert employee.id == 3
具有默认值的字段必须位于没有默认值的任何字段之后。
结果类具有一个额外的属性__annotations__
,该属性给出将字段名称 Map 到字段类型的字典。 (字段名称在_fields
属性中,默认值在_field_defaults
属性中,这两者都是 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}>'
Backward-compatible usage:
Employee = NamedTuple('Employee', [('name', str), ('id', int)])
在版本 3.6 中进行了更改:添加了对 PEP 526变量 Comments 语法的支持。
在版本 3.6.1 中进行了更改:添加了对默认值,方法和文档字符串的支持。
从 3.8 版开始不推荐使用,将在 3.9 版中删除:不推荐使用_field_types
属性,而推荐使用具有相同信息的更标准的__annotations__
属性。
在 3.8 版中进行了更改:_field_types
和__annotations__
属性现在是常规词典,而不是OrderedDict
的实例。
-
- class *
typing.
TypedDict
(* dict *)
- 一个简单的类型命名空间。在运行时,它等效于普通的dict。
- class *
TypedDict
创建一个字典类型,该字典类型期望其所有实例都具有一组特定的键,其中每个键都与一个一致类型的值相关联。在运行时不会检查此期望,而是仅由类型检查器强制执行。用法:
class Point2D(TypedDict):
x: int
y: int
label: str
a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK
b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check
assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
可以passPoint2D.__annotations__
和Point2D.__total__
访问用于自省的类型信息。要允许将此Function与不支持 PEP 526的 python 旧版本一起使用,TypedDict
支持两种其他等效的语法形式:
Point2D = TypedDict('Point2D', x=int, y=int, label=str)
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
默认情况下,所有键都必须存在于 TypedDict 中。pass指定总计可以覆盖此设置。用法:
class point2D(TypedDict, total=False):
x: int
y: int
这意味着 point2D TypedDict 可以Ellipsis任何键。类型检查器仅应支持 LiteralsFalse 或 True 作为 total 参数的值。默认是 True,它使在类主体中定义的所有项目都是必需的。
有关使用TypedDict
的更多示例和详细规则,请参见 PEP 589。
3.8 版的新Function。
类别
typing.
ForwardRef
- 用于字符串正向引用的内部类型表示的类。例如,
List["SomeClass"]
被隐式转换为List[ForwardRef("SomeClass")]
。此类不应由用户实例化,但是可以由自省工具使用。
- 用于字符串正向引用的内部类型表示的类。例如,
typing.
NewType
(* name , tp *)- 用于为类型检查器指示不同类型的帮助程序Function,请参见NewType。在运行时,它返回一个函数,该函数返回其参数。用法:
UserId = NewType('UserId', int)
first_user = UserId(1)
版本 3.5.2 中的新Function。
typing.
cast
(* typ , val *)- 将值强制转换为类型。
这将返回不变的值。对于类型检查器,这表明返回值具有指定的类型,但是在运行时我们有意不进行任何检查(我们希望此检查速度尽可能快)。
typing.
get_type_hints
(* obj * [,* globals * [,* locals *]])- 返回包含函数,方法,模块或类对象的类型提示的字典。
这通常与obj.__annotations__
相同。此外,pass在globals
和locals
命名空间中评估它们来处理编码为字符串 Literals 的前向引用。如有必要,如果设置的默认值等于None
,则为函数和方法 Comments 添加Optional[t]
。对于C
类,返回以相反的 Sequences 合并所有__annotations__
和C.__mro__
构成的字典。
typing.
get_origin
(* tp *)typing.
get_args
(* tp *)- 提供对通用类型和特殊键入形式的基本自省。
对于形式为X[Y, Z, ...]
的键入对象,这些函数返回X
和(Y, Z, ...)
。如果X
是内置类或collections类的通用别名,则将其标准化为原始类。对于不受支持的对象,分别返回None
和()
。例子:
assert get_origin(Dict[str, int]) is dict
assert get_args(Dict[int, str]) == (int, str)
assert get_origin(Union[int, str]) is Union
assert get_args(Union[int, str]) == (int, str)
3.8 版的新Function。
@
typing.
overload
@overload
装饰器允许描述支持参数类型的多种不同组合的函数和方法。必须在一系列@overload
装饰的定义之后紧跟一个非@overload
装饰的定义(对于相同的Function/方法)。@overload
修饰的定义仅出于类型检查器的目的,因为它们会被非@overload
修饰的定义覆盖,而后者则在运行时使用,但应由类型检查器忽略。在运行时,直接调用@overload
装饰的函数将引发NotImplementedError。重载的示例提供了比使用联合或类型变量可以表达的类型更精确的类型:
@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。
@
typing.
final
- 装饰器,用于向检查器指示不能重写修饰的方法,并且不能对修饰的类进行子类化。例如:
class Base:
@final
def done(self) -> None:
...
class Sub(Base):
def done(self) -> None: # Error reported by type checker
...
@final
class Leaf:
...
class Other(Leaf): # Error reported by type checker
...
这些属性没有运行时检查。有关更多详细信息,请参见 PEP 591。
3.8 版的新Function。
@
typing.
no_type_check
- 指示 Comments 不是类型提示的装饰器。
这可用作类或函数decorator。对于一个类,它递归地应用于该类中定义的所有方法(但不适用于其超类或子类中定义的方法)。
这会使Function变位。
@
typing.
no_type_check_decorator
- 装饰器为另一个装饰器提供no_type_check()效果。
这会将修饰符包装在no_type_check()中,将修饰的函数包装在装饰器中。
@
typing.
type_check_only
- 装饰器将类或函数标记为在运行时不可用。
该装饰器本身在运行时不可用。如果实现返回私有类的实例,则主要用于标记类型存根文件中定义的类:
@type_check_only
class Response: # private or not available at runtime
code: int
def get_header(self, name: str) -> str: ...
def fetch_response() -> Response: ...
请注意,不建议返回私有类的实例。通常最好公开此类类。
@
typing.
runtime_checkable
- 将协议类标记为运行时协议。
这样的协议可以与isinstance()和issubclass()一起使用。当将其应用于非协议类时,它将引发TypeError。这允许进行简单的结构检查,与collections.abc中的“一招小马”(如Iterable)非常相似。例如:
@runtime_checkable
class Closable(Protocol):
def close(self): ...
assert isinstance(open('/some/file'), Closable)
警告: 这只会检查所需方法的存在,而不检查其类型签名!
3.8 版的新Function。
from typing import NoReturn
def stop() -> NoReturn:
raise RuntimeError('no way')
3.5.4 版中的新Function。
版本 3.6.2 中的新Function。
typing.
Union
- 联合类型;
Union[X, Y]
表示 X 或 Y。
- 联合类型;
要定义并集,请使用例如Union[int, str]
。细节:
参数必须是类型,并且必须至少有一个。
unions 的 unions 是扁平的,例如:
Union[Union[int, str], float] == Union[int, str, float]
- 单个参数的并集消失,例如:
Union[int] == int # The constructor actually returns int
- 多余的参数将被跳过,例如:
Union[int, str, int] == Union[int, str]
- 比较并集时,将忽略参数 Sequences,例如:
Union[int, str] == Union[str, int]
您不能继承或实例化联合。
您不能写
Union[X][Y]
。您可以使用
Optional[X]
作为Union[X, None]
的简写。
在版本 3.7 中进行了更改:在运行时不要从联合中删除显式子类。
typing.
Optional
- Optional type.
Optional[X]
等效于Union[X, None]
。
请注意,这与可选参数的概念不同,后者是默认参数。具有默认值的可选参数仅在其类型 Comments 中不需要Optional
限定符,因为它是可选参数。例如:
def foo(arg: int = 0) -> None:
...
另一方面,如果允许使用显式值None
,则无论参数是否可选,都可以使用Optional
。例如:
def foo(arg: Optional[int] = None) -> None:
...
typing.
Tuple
- Tuples 类型;
Tuple[X, Y]
是两个项目的 Tuples 的类型,第一个项目的类型为 X,第二个项目的类型为 Y。空 Tuples 的类型可以写为Tuple[()]
。
- Tuples 类型;
示例:Tuple[T1, T2]
是对应于类型变量 T1 和 T2 的两个元素的 Tuples。 Tuple[int, float, str]
是一个整数,一个浮点数和一个字符串的 Tuples。
要指定同构类型的可变长度 Tuples,请使用 Literals Ellipsis号,例如Tuple[int, ...]
。普通的Tuple等效于Tuple[Any, ...]
,然后等效于tuple。
typing.
Callable
- 可调用类型;
Callable[[int], str]
是(int)-> str 的函数。
- 可调用类型;
订阅语法必须始终与两个值一起使用:参数列表和返回类型。参数列表必须是类型列表或Ellipsis号。返回类型必须是单个类型。
没有语法指示可选参数或关键字参数。这种函数类型很少用作回调类型。 Callable[..., ReturnType]
(大写Ellipsis号)可用于使用任何数量的参数并返回ReturnType
来键入提示可调用的提示。普通的Callable等效于Callable[..., Any]
,然后等效于collections.abc.Callable。
typing.
Literal
- 一种类型,可用于指示类型检查器相应的变量或函数参数具有等于提供的 Literals(或几个 Literals 之一)的值。例如:
def validate_simple(data: Any) -> Literal[True]: # always returns True
...
MODE = Literal['r', 'rb', 'w', 'wb']
def open_helper(file: str, mode: MODE) -> str:
...
open_helper('/some/path', 'r') # Passes type check
open_helper('/other/path', 'typo') # Error in type checker
Literal[...]
不能被子类化。在运行时,可以将任意值用作Literal[...]
的类型参数,但是类型检查器可能会施加限制。有关 Literals 类型的更多详细信息,请参见 PEP 586。
3.8 版的新Function。
typing.
ClassVar
- 用于标记类变量的特殊类型构造。
正如在 PEP 526中引入的那样,包装在 ClassVar 中的变量 Comments 指示打算将给定属性用作类变量,并且不应在该类的实例上设置该属性。用法:
class Starship:
stats: ClassVar[Dict[str, int]] = {} # class variable
damage: int = 10 # instance variable
ClassVar仅接受类型,无法进一步订阅。
ClassVar本身不是类,因此不应与isinstance()或issubclass()一起使用。 ClassVar不会更改 Python 运行时行为,但可以由第三方类型检查器使用。例如,类型检查器可能会将以下代码标记为错误:
enterprise_d = Starship(3000)
enterprise_d.stats = {} # Error, setting class variable on instance
Starship.stats = {} # This is OK
版本 3.5.3 中的新Function。
typing.
Final
- 一种特殊的类型构造,用于指示类型检查器,该名称不能在子类中重新分配或覆盖。例如:
MAX_SIZE: Final = 9000
MAX_SIZE += 1 # Error reported by type checker
class Connection:
TIMEOUT: Final[int] = 10
class FastConnector(Connection):
TIMEOUT = 1 # Error reported by type checker
这些属性没有运行时检查。有关更多详细信息,请参见 PEP 591。
3.8 版的新Function。
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
- 由第三方静态类型检查器假定为
True
的特殊常量。在运行时为False
。用法:
- 由第三方静态类型检查器假定为
if TYPE_CHECKING:
import expensive_mod
def fun(arg: 'expensive_mod.SomeType') -> None:
local_var: expensive_mod.AnotherType = other_fun()
请注意,第一种类型的 Comments 必须用引号引起来,使其成为“前向引用”,以对解释器运行时隐藏expensive_mod
引用。不会评估局部变量的类型 Comments,因此不需要将第二个 Comments 用引号引起来。
版本 3.5.2 中的新Function。