如何解决回调协议 - 我们什么时候需要双下划线前缀?
mypy docs 阅读
可以使用回调协议和:py:data:~typing.Callable
类型
可互换。 :py:meth:__call__ <object.__call__>
方法中的关键字参数名称必须相同,除非是 double
使用下划线前缀。例如:
typing_extensions import Protocol
T = TypeVar('T')
class copy(Protocol):
def __call__(self,__origin: T) -> T: ...
copy_a: Callable[[T],T] copy_b: copy
copy_a = copy_b # OK copy_b = copy_a # Also OK ```
然而,如果我们删除 __origin
之前的双下划线前缀,这个例子也适用。例如
$ cat t.py
from typing import Callable,TypeVar
from typing_extensions import Protocol
T = TypeVar('T')
class copy(Protocol):
def __call__(self,origin: T) -> T: ...
copy_a: Callable[[T],T]
copy_b: copy
copy_a = copy_b # OK
copy_b = copy_a # Also OK
$ mypy t.py
Success: no issues found in 1 source file
所以,这个例子对我来说不清楚。我们什么时候需要双下划线前缀?
解决方法
命名参数可用于代替匿名参数,因此协议可用作 Callable 的值。第一个赋值 copy_a = copy_b
默默地将 copy_a
提升为 Copy
,然后可以有效地赋值给 copy_b: Copy
。
...
copy_a = copy_b # copy_a is a Copy now!
copy_b = copy_a # assign copy_a: Copy to copy_b: Copy
reveal_type(copy_a) # Revealed type is 'aaa_testbed.Copy'
交换赋值意味着 copy_b = copy_a
发生,而 copy_a
仍然是匿名类型。这会触发预期的错误:
...
copy_b = copy_a # Incompatible types in assignment (expression has type "Callable[[T],T]",variable has type "Copy")
copy_a = copy_b
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。