前言
最近在看FATE源码时,看到函数定义中出现了这个用法,记录一下
Python 运行时不强制执行函数和变量类型注解,但这些注解可用于类型检查器、IDE、静态检查器等第三方工具。
参考文档: typing —— 类型提示支持
函数中指定参数类型
def greeting(name: str) -> str:
return 'Hello ' + name
在greeting
函数中,参数name: str
表示name
的类型是str
,-> str
表示返回类型也是str
类型别名
将复杂的类型用更简洁的形式表示
将类型作为常量赋给别名,就可以定义类型别名
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])
在该例子中,Vector
表示和list[float]
相同类型,可以互换
正如前面所说,类型别名适用于简化复杂的类型签名
def test(msg: str) -> None:
...
注意:None
是一种类型提示特例,已被type(None)取代
NewType
使用NewType
辅助类来创建不同的类型
函数原型:
def NewType(name, tp):
"""NewType creates simple unique types with almost zero
runtime overhead. NewType(name, tp) is considered a subtype of tp
by static type checkers. At runtime, NewType(name, tp) returns
a dummy function that simply returns its argument. Usage::
UserId = NewType('UserId', int)
def name_by_id(user_id: UserId) -> str:
...
UserId('user') # Fails type check
name_by_id(42) # Fails type check
name_by_id(UserId(42)) # OK
num = UserId(5) + 1 # type: int
"""
def new_type(x):
return x
new_type.__name__ = name
new_type.__supertype__ = tp
return new_type
注释中有这么一句话,At runtime, NewType(name, tp) returns a dummy function that simply returns its argument,类立即返回你传递给它的任何参数
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
静态类型检查器把新类型当作原始类型的子类,适用于捕捉逻辑错误
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
# 不能使用UserId作为参数创建类
class AdminUserId(UserId): pass
然而,我们可以在 "派生的" NewType
的基础上创建一个NewType
。
from typing import NewType
UserId = NewType('UserId', int)
ProUserId = NewType('ProUserId', UserId)
同时,ProUserId
的类型检查也可以按预期执行。
Comments NOTHING