问题
>>> from typing import overload
>>> @overload
... def hello(s: int):
... return "Got an integer!"
>>> def hello(s: str):
... return "Got a string"
Why does the calling hello(1)
call the function with the string argument? Ideally, the @overload
operator should handle it, right?
回答1:
Unfortunately, python does not allow function overloading. Each time you think you are overloading function, you are just overwriting previous function declaration. Quote from the docs:
The @overload decorator allows describing functions and methods that support multiple different combinations of argument types. A series of @overload-decorated definitions must be followed by exactly one non-@overload-decorated definition (for the same function/method). The @overload-decorated definitions are for the benefit of the type checker only, since they will be overwritten by the non-@overload-decorated definition, while the latter is used at runtime but should be ignored by a type checker. At runtime, calling a @overload-decorated function directly will raise NotImplementedError.
The correct usage of typing.overload
is as follows:
from typing import overload
@overload
def hello(s: int) -> str:
...
@overload
def hello(s: str) -> str:
...
def hello(s):
if isinstance(s, int):
return "Got an integer!"
if isinstance(s, str):
return "Got a string"
raise ValueError('You must pass either int or str')
if __name__ == '__main__':
print(hello(1))
To show the actual benefit of typing.overload
lets change def hello(s: int)
to return int
instead of str
:
from typing import overload
@overload
def hello(s: int) -> int:
...
@overload
def hello(s: str) -> str:
...
def hello(s):
if isinstance(s, int):
return "Got an integer!"
if isinstance(s, str):
return "Got a string"
raise ValueError('You must pass either int or str')
if __name__ == '__main__':
print(hello(1))
a = hello(1) + 1
b = hello(1) + 'a'
Note, that the actual implementation still returns str
- python does not perform any checks here. However, PyCharm raises a warning:
mypy
also complains about invalid types:
➜ mypy test.py
test.py:25: error: Unsupported operand types for + ("int" and "str")
The purpose of typing
module is to allow third party tools to perform static checking of your code. There is no magic here - all types are ignored at runtime.
来源:https://stackoverflow.com/questions/52034771/overload-decorator-in-typings-module-doesnt-seem-to-behave-as-expected