Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 打字模块中的重载修饰符不';Don’我的行为似乎不像预期的那样_Python_Python 3.x_Overloading_Strong Typing - Fatal编程技术网

Python 打字模块中的重载修饰符不';Don’我的行为似乎不像预期的那样

Python 打字模块中的重载修饰符不';Don’我的行为似乎不像预期的那样,python,python-3.x,overloading,strong-typing,Python,Python 3.x,Overloading,Strong Typing,为什么调用的hello(1)使用字符串参数调用函数?理想情况下,@重载操作符应该处理它,对吗?不幸的是,python不允许函数重载。每次您认为您是在重载函数时,您只是在覆盖前面的函数声明。引自: @重载装饰器允许描述 支持多种不同的参数类型组合。一系列 @重载修饰定义后面必须紧跟一个 非重载修饰定义(对于相同的函数/方法)最新版本 @重载修饰定义是为了该类型的利益 仅限checker,因为它们将被 非重载修饰定义,而后者用于 运行时,但应被类型检查器忽略。在运行时,调用 @直接重载修饰函数将引发

为什么调用的
hello(1)
使用字符串参数调用函数?理想情况下,
@重载
操作符应该处理它,对吗?

不幸的是,python不允许函数重载。每次您认为您是在重载函数时,您只是在覆盖前面的函数声明。引自:

@重载装饰器允许描述 支持多种不同的参数类型组合。一系列 @重载修饰定义后面必须紧跟一个 非重载修饰定义(对于相同的函数/方法)最新版本 @重载修饰定义是为了该类型的利益 仅限checker,因为它们将被 非重载修饰定义,而后者用于 运行时,但应被类型检查器忽略。在运行时,调用 @直接重载修饰函数将引发NotImplementedError

键入.重载的正确用法如下:

>>> from typing import overload

>>> @overload
... def hello(s: int):
...     return "Got an integer!"

>>> def hello(s: str):
...     return "Got a string"
要显示
键入的实际好处。重载
允许更改
def hello(s:int)
以返回
int
,而不是
str

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))
注意,实际实现仍然返回
str
——python在这里不执行任何检查。但是,PyCharm提出了一个警告:

mypy
还抱怨无效类型:

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'
输入模块的目的是允许第三方工具对代码执行静态检查。这里没有什么神奇之处——所有类型在运行时都会被忽略

➜ mypy test.py 
test.py:25: error: Unsupported operand types for + ("int" and "str")
蟒蛇>
小绿平托

小红克尔维特

你需要修饰这两个定义,否则你只是用一个普通函数重写了
hello
中的任何内容。准确地说,应该只修饰存根函数。调用修饰函数将引发
NotImplementedError
重载
的思想是用实际的实现覆盖存根。那么如果我们要检查类型,
@重载
有什么意义呢?编辑:没有意义。明白了。我怀疑的原因是Pycon的一次谈话,演讲者做了问题中提到的事情。奇怪。@saruftw请检查更新的答案。简而言之,
输入
模块(尤其是在
@重载
中)的要点是允许第三方工具(例如mypy)运行静态检查。谢谢你的解释。
# tested in Python 3.8.5 32-bit
# overloads the method
# imports libraries from the base distribution 
# confuses some linters
# undermines type-hinting by documenting *kwargs or dispatch signature

from functools import singledispatch

class Car:
    def __init__(self, color: str, brand: str) -> None:
        self.color = color
        self.brand = brand


@singledispatch
def describe_car(color: str, kind: str) -> str:
    return "Little " + color + " " + kind

@describe_car.register(Car)
def _(car: Car) -> str:
        return describe_car(car.color, car.brand)


newcar = Car("red", "corvette")

print(describe_car("green", "pinto"))
print(describe_car(newcar))