– 支持类型提示 – 开发工具(Python教程)(参考资料)
typing– 支持类型提示
版本3.5中的新功能.
源代码: Lib / typing.py
注意
打字模块已经在临时基础上包含在标准库中。如果核心开发人员认为有必要,可能会添加新功能,即使在次要版本之间API也可能会发生变化.
该模块支持PEP 484 和PEP 526 。最基本的支持包括类型Any, Union,Tuple, Callable, TypeVar和Generic。有关完整规格,请参阅 PEP 484 。Fora简化了类型提示的介绍,请参阅PEP 483 .
下面的函数接受并返回一个字符串并注释如下:
def greeting(name: str) -> str: return "Hello " + name
在函数greeting中,参数name应该是类型str和返回类型str。子类型被接受为参数.
类型别名
通过将类型分配给别名来定义类型别名。在这个例子中,Vector和List[float]将被视为可互换的同义词:
from typing import ListVector = 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, SequenceConnectionOptions = 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: ...
NewType
替换使用NewType()用于创建不同类型的辅助函数:
from typing import NewTypeUserId = NewType("UserId", int)some_id = UserId(524313)
静态类型检查器将新类型视为原始类型的子类。这有助于捕获逻辑错误:
def get_user_name(user_id: UserId) -> str: ...# typechecksuser_a = get_user_name(UserId(42351))# does not typecheck; an int is not a UserIduser_b = get_user_name(-1)
您仍然可以对int类型的变量执行所有UserId操作,但结果将始终为int类型。这让你可以在任何地方UserId传入int可能是预期的,但是会阻止你以无效的方式创建一个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)在运行时总是非常的.
这也意味着无法创建Derived的子类型,因为它是运行时的标识函数,而不是实际类型:
from typing import NewTypeUserId = NewType("UserId", int)# Fails at runtime and does not typecheckclass AdminUserId(UserId): pass
但是,可以创建一个NewType()基于’派生’NewType:
from typing import NewTypeUserId = NewType("UserId", int)ProUserId = NewType("ProUserId", UserId)
和typechecking为ProUserId将按预期工作.
参见 PEP 484 了解更多细节.
注意
回想一下,使用类型别名声明两种类型equivalent彼此。做Alias = Original将制作静态类型的checkertreat Alias作为exactly equivalent至 Original在所有情况下。当你想要简化复杂类型签名时,这很有用.
相比之下,NewType声明一种类型是subtype的另一种类型。做Derived = NewType("Derived", Original)将制作静态类型搜索器Derived作为一个 subclass对Original,表示值Original不能在类型为Derived是期待。当你想以最小的运行时成本来防止逻辑错误时,这很有用.
版本3.5.2.
可用
期望特定签名的回调函数的框架可以使用Callable[[Arg1Type, Arg2Type], ReturnType].
进行类型提示。例如:
from typing import Callabledef feeder(get_next_item: Callable[[], str]) -> None: # Bodydef async_query(on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]) -> None: # Body
可以通过用文字省略号替换参数列表来声明可调用的返回类型而不指定调用签名在类型提示中:Callable[..., ReturnType].
泛型
由于无法以通用方式静态推导容器中保存的对象的类型信息,因此抽象基类已扩展为supportsubscription以表示容器元素的预期类型。
from typing import Mapping, Sequencedef notify_by_email(employees: Sequence[Employee], overrides: Mapping[str, str]) -> None: ...
from typing import Sequence, TypeVarT = TypeVar("T") # Declare type variabledef first(l: Sequence[T]) -> T: # Generic function return l[0]
用户定义的泛型类型
用户定义的类可以定义为泛型类
from typing import TypeVar, Genericfrom logging import LoggerT = 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采用单一类型参数T。这也使得T作为类体内的类型有效.
Generic基类使用定义__getitem__()的元类,以便LoggedVar[t]有效作为类型:
from typing import Iterabledef 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, SizedT = TypeVar("T")class LinkedList(Sized, Generic[T]): ...
进行多重继承当从泛型类继承时,可以修复某些类型变量:
from typing import TypeVar, MappingT = TypeVar("T")class MyDict(Mapping[str, T]): ...
在这种情况下MyDict只有一个参数,T.
对于每个位置,使用通用类而不指定类型参数假设为Any。在以下示例中,MyIterable不是通用的,但隐式继承自Iterable[Any]:
from typing import Iterableclass MyIterable(Iterable): # Same as Iterable[Any]
也支持用户定义的泛型类别别名。示例:
from typing import TypeVar, Iterable, Tuple, UnionS = 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)
Generic使用的元类是abc.ABCMeta的子类。泛型类可以是包含抽象方法或属性的ABC,泛型类也可以包含ABC作为没有元类冲突的基类。不支持通用元类。参数化语法的结果是缓存的,并且输入模块中的大多数类型都是可以兼容的,可以兼容.
Any类型
一种特殊的类型的类型是Any。静态类型检查器将处理与Any和Any兼容的类型,因为它与每种类型兼容.
这意味着可以对Any上的类型进行任何操作或方法调用,并将其分配给任何变量:
from typing import Anya = None # type: Anya = [] # OKa = 2 # OKs = "" # type: strs = a # OKdef foo(item: Any) -> int: # Typechecks; "item" could be any type, # and that type might have a "bar" method item.bar() ...
请注意,在将类型为Any的值分配给更精确的类型时,不会执行类型检查。例如,静态类型检查器在分配a到s即使s被声明为str类型并且接收int值atruntime!
此外,所有没有返回类型或参数类型的函数都会明确地默认使用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用作escape hatch当你需要混合动态和静态类型的代码时
对比Any与object。相近 Any,每种类型都是object的子类型。但是,与Any不同,反之则不然:object是not每个其他类型的子类型.
这意味着当值的类型为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 objecthash_a(42)hash_a("foo")# Typechecks, since Any is compatible with all typeshash_b(42)hash_b("foo")
使用object表示值可以是typesafemanner中的任何类型。使用Any表示值是动态类型的.
类,函数和装饰器
模块定义了以下类,函数和装饰器:
- class
typing.TypeVar -
Type variable.
Usage:
T = TypeVar("T") # Can be anythingA = 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]*ndef 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()不应该与类型一起使用.通过传递
covariant=True或contravariant=True,类型变量可以标记为协变或逆变。见 PEP 484 更多细节。默认情况下,类型变量是不变的。或者,类型变量可以使用bound=<type>。这意味着类型变量替换(显式或隐式)的实际类型必须是边界类型的子类,请参阅PEP 484 .
- class
typing.Generic -
通用类型的抽象基类.
泛型类型通常通过从具有一个或多个类型变量的此类的实例继承来声明。例如,泛型映射类型可以定义为:
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
- class
typing.Type(Generic[CT_co]) -
用
C可以接受C。Incontrast,一个用Type[C]可以接受类本身的值 – 具体来说,它会接受class object的C。例如: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。类型检查器应该标记违反此规则的行为,但是也应该允许子类中的构造函数调用与指定基类中的构造函数调用匹配。如何处理这种特殊情况的类型检查器可能会在以后的修改中改变PEP 484 .Type的唯一合法参数是类,Any,类型变量,以及任何这些类型的联合。例如:def new_non_team_user(user_class: Type[Union[BaseUser, ProUser]]): ...
Type[Any]相当于Type,相当于type,这是Python的元类层次结构的根源.版本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 -
用一种抽象方法的ABC
__int__.
- class
typing.SupportsFloat -
用一种抽象方法的ABC
__float__.
- class
typing.SupportsComplex -
用一种抽象方法的ABC
__complex__.
- class
typing.SupportsBytes -
用一种抽象方法的ABC
__bytes__.
- class
typing.SupportsAbs -
用一种抽象方法的ABC
__abs__它的返回类型是协变的.
- class
typing.SupportsRound -
用一种抽象方法的ABC
__round__它的返回类型是协变的.
- class
typing.Hashable -
的别名
collections.abc.Hashable
- class
typing.Sized -
的别名
collections.abc.Sized
- class
typing.Collection(Sized, Iterable[T_co], Container[T_co]) -
的通用版本
collections.abc.Collection版本3.6.
- 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。这种类型可以用如下:def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: return word_list[word]
- class
typing.MutableMapping(Mapping[KT, VT]) -
的通用版本
collections.abc.MutableMapping.
- class
typing.Sequence(Reversible[T_co], Collection[T_co]) -
的通用版本
collections.abc.Sequence.
- class
typing.MutableSequence(Sequence[T]) -
的通用版本
collections.abc.MutableSequence.
- class
typing.ByteString(Sequence[int]) -
的通用版本
collections.abc.ByteString.这种类型代表
bytes,bytearray,和memoryview.作为这种类型的速记,
bytes可用于注释上述任何类型的参数.
- class
typing.Deque(deque, MutableSequence[T]) -
的通用版本
collections.deque.版本3.6.1.
- class
typing.List(list, MutableSequence[T]) -
的通用版
list。用于注释返回类型。要注释参数,最好使用抽象集合类型,如Sequence或Iterable.这种类型可以使用如下:
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.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.
- class
typing.Coroutine(Awaitable[V_co], Generic[T_co T_contra, V_co]) -
的通用版本
collections.abc.Coroutine类型变量的方差和顺序对应于的变量和顺序Generator, 例如:from typing import List, Coroutinec = None # type: Coroutine[List[str], str, int]...x = c.send("hi") # type: List[str]async def bar() -> None: x = await c # type: int
- class
typing.AsyncIterable(Generic[T_co]) -
的通用版本
collections.abc.AsyncIterable.
- class
typing.AsyncIterator(AsyncIterable[T_co]) -
的通用版本
collections.abc.AsyncIterator.
- class
typing.Dict(dict, MutableMapping[KT, VT]) -
的通用版本
dict。用于注释返回类型。要注释参数,最好使用抽象集合类型,如Mapping.这种类型可以使用如下:
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.ChainMap(collections.ChainMap, MutableMapping[KT, VT]) -
的通用版本
collections.ChainMap.版本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"
请注意,与输入模块中的许多其他泛型不同,
SendType的Generator表现不一致,不是共变或不变的.如果您的发电机只会产生数值,请将
SendType和ReturnType设为None:def infinite_stream(start: int) -> Generator[int, None, None]: while True: yield start start += 1
或者,将发生器注释为返回类型为
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]注释。例如: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)
或者,将您的生成器注释为具有
AsyncIterable[YieldType]要么AsyncIterator[YieldType]:async def infinite_stream(start: int) -> AsyncIterator[int]: while True: yield start start = await increment(start)
版本3.5.4.
- class
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.
- class
typing.IO - class
typing.TextIO - class
typing.BinaryIO -
通用型
IO[AnyStr]及其子类TextIO(IO[str])和BinaryIO(IO[bytes])表示由open().
- class
typing.Pattern - class
typing.Match -
返回的I / O流的类型这些类型的别名对应于
re.compile()和re.match()的返回类型。这些类型(和相应的功能)在AnyStr并且可以通过写Pattern[str],Pattern[bytes],Match[str]或Match[bytes].
- class
typing.NamedTuple -
来命名具体版本的namedtuple.
使用
class Employee(NamedTuple): name: str id: int
这相当于:
Employee = collections.namedtuple("Employee", ["name", "id"])要给字段一个默认值,你可以在类体中指定它:
class Employee(NamedTuple): name: str id: int = 3employee = Employee("Guido")assert employee.id == 3具有默认值的字段必须位于没有默认值的任何字段之后.
结果类有两个额外的属性:
_field_types,将字段名称映射到类型,以及_field_defaults,一个dictmapping字段命名为默认值。(字段名称在_fields属性中,它是namedtuple API的一部分。)NamedTuple子类也可以有docstrings和方法: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更改:增加对PEP 526 变量注释语法.
在版本3.6.1中更改:添加了对默认值,方法和文档字符串的支持.
typing.NewType(typ)-
帮助函数向类型检查器指示不同的类型,请参阅NEWTYPE 。在运行时,它返回一个返回参数的函数。使用方法:
UserId = NewType("UserId", int)first_user = UserId(1)3.5.2版中的新品.
typing.cast(typ, val)-
一个类型的值
这将返回值不变。对于类型检查器,thissignals返回值具有指定的类型,但是atruntime我们故意不检查任何东西(我们希望它尽可能快).
typing.get_type_hints(obj[, globals[, locals] ] )-
返回包含函数,方法,模块或类对象的类型提示的字典.
这通常与
obj.__annotations__。另外,编码为字符串文字的前向引用是通过在globals和locals命名空间中评估它们来处理的。如有必要,Optional[t]如果设置了等于None的defaultvalue,则为函数和方法注释添加。对于一个类C,通过以相反的顺序合并所有__annotations__和C.__mro__构造的returna字典.
@typing.overload-
@overloaddecorator允许描述支持多种不同的参数类型组合的函数和方法。一系列@overload– 修改后的定义必须紧跟在后面 –@overload– 修改定义(对于相同的功能/方法)。@overload– 修改后的定义只是为了类型检查器的好处,因为它们将被thenon –@overload– 装饰定义覆盖,而后者使用atruntime但应该被类型检查器忽略。在运行时,直接调用@overload– 装饰函数会引发NotImplementedError。提供比使用union或类型变量表达更精确的类型的重载示例:@overloaddef process(response: None) -> None: ...@overloaddef process(response: int) -> Tuple[int, str]: ...@overloaddef process(response: bytes) -> str: ...def process(response): <actual implementation>
请参阅 PEP 484 以获取详细信息并与其他类型语义进行比较.
@typing.no_type_check-
装饰者表示注释不是类型提示.
这个作为类或功能装饰者。对于一个类,它递归地应用于该类中定义的所有方法(但不适用于在其超类或子类中定义的方法).
这会使函数变异到位
typing.Any-
特殊类型表示不受约束的类型
- 每种类型都兼容
Any. Any兼容各种类型.
- 每种类型都兼容
typing.NoReturn-
表示函数永不返回的特殊类型。例如:
from typing import NoReturndef stop() -> NoReturn: raise RuntimeError("no way")版本3.6.5.
typing.Union-
联盟类型;
Union[X, Y]是指X或Y.要定义联合,请使用例如
Union[int, str]。细节:-
参数必须是类型,并且必须至少有一个.
-
工会的联盟被夷为平地,例如:
Union[Union[int, str], float] == Union[int, str, float]
-
一个论点的联盟消失,例如:
Union[int] == int # The constructor actually returns int
-
冗余的论点被跳过,例如:
Union[int, str, int] == Union[int, str]
-
比较联合时,参数顺序被忽略,例如:
Union[int, str] == Union[str, int]
-
你不能子类化或实例化一个联盟.
-
你不能写
Union[X][Y]. -
您可以使用
Optional[X]作为的简写Union[X, None].
在版本3.7中更改:不要在运行时从联合中删除显式子类.
-
typing.Optional-
可选类型.
Optional[X]相当于Union[X, None].请注意,这与可选参数的概念不同,可选参数是具有默认参数的参数。使用adefault的可选参数不需要
Optional关于typeannotation的限定符只是因为它是可选的。例如:def foo(arg: int = 0) -> None: ...
另一方面,如果允许显式值
None,则使用Optional是否合适,论证是否是可选的。例如:def foo(arg: Optional[int] = None) -> None: ...
typing.Tuple-
元组类型;
Tuple[X, Y]是两个项目的元组的类型,第一项是X型,第二项是Y.示例:
Tuple[T1, T2]是对应于类型变量T1和T2的两个元素的元组。Tuple[int, float, str]是一个int,一个浮子和一个字符串的元组.要指定同类型的可变长度元组,请使用文字省略号,例如,
Tuple[int, ...]。平原Tuple相当于Tuple[Any, ...],反过来tuple.
typing.Callable-
可赎回型;
Callable[[int], str]是(int) – &gt;的函数。str.订阅语法必须始终与两个值一起使用:参数列表和返回类型。参数列表必须是类型列表或省略号;返回类型必须是单一类型.
没有语法来指示可选或关键字参数;这些函数类型很少用作回调类型.
Callable[..., ReturnType](字面省略号)可以使用totype提示一个可调用的任意数量的参数并返回ReturnType。一个简单的Callable相当于Callable[..., Any],反过来collections.abc.Callable.
typing.ClassVar-
用于标记类变量的特殊类型构造.
如在介绍PEP 526 ,包含在ClassVar中的变量注释,表示给定属性旨在用作类变量,不应在该类的实例上设置。用法:
class Starship: stats: ClassVar[Dict[str, int]] = {} # class variable damage: int = 10 # instance variableClassVar只接受类型,不能进一步订阅.ClassVar本身不是一个类,不应该与isinstance()或issubclass().ClassVar不会更改Python运行时行为,但可以由第三方类型检查器使用。例如,类型checkermight将以下代码标记为错误:enterprise_d = Starship(3000)enterprise_d.stats = {} # Error, setting class variable on instanceStarship.stats = {} # This is OK版本3.5.3.
typing.AnyStr-
AnyStr是一个定义为AnyStr = TypeVar("AnyStr", str, bytes).它用于可以接受任何类型的字符串而不允许不同类型的字符串混合的函数。例如:
def concat(a: AnyStr, b: AnyStr) -> AnyStr: return a + bconcat(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-
由第三方statictype checkers假定为
True的特殊常量。在运行时是False。用法:if TYPE_CHECKING: import expensive_moddef fun(arg: "expensive_mod.SomeType") -> None: local_var: expensive_mod.AnotherType = other_fun()
请注意,第一个类型的注释必须用引号括起来,使其成为“前向引用”,以隐藏来自解释器运行时的
expensive_mod引用。对于局部变量的类型注释是值得评估的,因此第二个注释不需要用引号括起来新版本3.5.2.
评论被关闭。