To the best of my knowledge, there is no direct workaround on this [1], but there is another elegant way to achieve exactly that:
我们可以利用typing
s NamedTuple
创建一个保存参数的对象:
ConsumeContext = NamedTuple('ConsumeContext', [('a', int), ('b', str)])
现在我们定义consume
方法接受它作为参数:
def consume(*, consume_context : ConsumeContext) -> None:
print(f'a : {consume_context.a} , b : {consume_context.b}')
整个代码是:
from typing import NamedTuple
ConsumeContext = NamedTuple('ConsumeContext', [('a', int), ('b', str)])
def consume(*, consume_context : ConsumeContext) -> None:
print(f'a : {consume_context.a} , b : {consume_context.b}')
ctx = ConsumeContext(a=1, b='sabich')
consume(consume_context=ctx)
运行 mypy 会产生:
Success: no issues found in 1 source file
它会认识到a
and b
是参数,并批准这一点。
运行代码将输出:
a : 1 , b : sabich
然而,如果我们改变b
如果不是字符串,mypy 会抱怨:
foo.py:9: error: Argument "b" to "ConsumeContext" has incompatible type "int"; expected "str"
Found 1 error in 1 file (checked 1 source file)
通过这种方式,我们通过定义一次方法的参数和类型来实现对方法的类型检查。
[1] Because if either defining TypedDict
or function signature, based on the other, would require to know the other's __annotations__
, which is not known on check-time, and defining a decorator to cast types on run-time misses the point of type checking.