Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
220 views
in Technique[技术] by (71.8m points)

python - Callback protocols - when do we need the double underscore prefix?

The mypy docs read

Callback protocols and :py:data:~typing.Callable types can be used interchangeably. Keyword argument names in :py:meth:__call__ <object.__call__> methods must be identical, unless a double underscore prefix is used. For example:

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    ```

However, this example also works if we remove the double underscore prefix from before __origin. E.g.

$ 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

So, this example isn't clear to me. When do we need the double underscore prefix?

question from:https://stackoverflow.com/questions/66068202/callback-protocols-when-do-we-need-the-double-underscore-prefix

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A named parameter can be used in placed of an anonymous parameter, so the Protocol works as a value for the Callable. The first assignment copy_a = copy_b silently promotes copy_a to a Copy, which is then valid to assign to 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'

Swapping the assignment means copy_b = copy_a happens while copy_a is still the anonymous type. This triggers the expected error:

...

copy_b = copy_a  # Incompatible types in assignment (expression has type "Callable[[T], T]", variable has type "Copy")
copy_a = copy_b

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...