gpt4 book ai didi

python - 3.5 : Type Hinting and Method Overloading

转载 作者:太空宇宙 更新时间:2023-11-03 15:01:24 24 4
gpt4 key购买 nike

编辑:我目前误解了该功能。 It's not designed for multiple dispatch :

NOTE: While it would be possible to provide a multiple dispatch implementation using this syntax, its implementation would require using sys._getframe() , which is frowned upon. Also, designing and implementing an efficient multiple dispatch mechanism is hard, which is why previous attempts were abandoned in favor of functools.singledispatch() . (See PEP 443 , especially its section "Alternative approaches".) In the future we may come up with a satisfactory multiple dispatch design, but we don't want such a design to be constrained by the overloading syntax defined for type hints in stub files. It is also possible that both features will develop independent from each other (since overloading in the type checker has different use cases and requirements than multiple dispatch at runtime -- e.g. the latter is unlikely to support generic types).

====

我离开 Java 已经有一段时间了,现在我要回到 Python 3.5。我想使用新的类型提示功能,但我在方法重载方面遇到了麻烦。从我对该功能的阅读来看,这应该得到支持。

这是我正在做的一个快速的小类(class):

licensing.pyi(注意pyi)

import typing
import gitlab


class LicensingChecker(object):
@typing.overload
def __init__(self, url: str, api_key: str) -> None: ...
@typing.overload
def __init__(self, gl: gitlab.Gitlab) -> None: ...

def iter_projects(self) -> typing.Iterator[str]: ...

licensing.py

import gitlab
import string


class LicenseChecker(object):
def __init__(self, gl):
self.gl = gl

def __init__(self, url, api_key):
self.gl = gitlab.Gitlab(url, api_key)

def iter_projects(self):
p = set()
for i in string.ascii_lowercase:
for x in self.gl.projects.search(i):
if x not in p:
p.add(x)
yield x.name

这是一个玩具示例,但这个想法相当传统。我提供了两个构造函数,一个采用现有的 gitlab 客户端,另一个将实例化它。 (此脚本不需要双重构造函数,但我看到了 @typing.overload 并想看看它是如何工作的。)

Pycharm 和 Cpython 似乎对这段代码很满意,但第一个构造函数是不可访问的——就像 @typing.overload 装饰器不起作用:

>>> import gitlab
>>> import licensing
>>> licensing.LicenseChecker(gitlab.Gitlab('https://blah.blah.blah/gitlab', 'hunter2'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'api_key'

我必须做一些特别的事情才能使重载工作吗?目前,我只是调用内置的 REPL 或 ipython。

最佳答案

Untyped Python 不支持重载。您的第二个 __init__ 正在覆盖第一个,因此是错误。您需要编写一个带有运行时类型检查的 __init__:

def __init__(self, arg1, arg2=None):
if isinstance(arg1, gitlab.Gitlab) and arg2 is None:
self.gl = arg1
elif arg1 is not None and arg2 is not None:
self.gl = gitlab.Gitlab(arg1, arg2)
else:
raise TypeError('........')

(有functools.singledispatch可以模拟只有一个参数改变类型的重载,但它不适合你的情况)


@typing.overload 装饰器只是告诉类型检查器参数可以有多种组合,这并不意味着您现在可以在两个不同的同名函数中编写实现。来自 PEP 484 :

Uses of the @overload decorator as shown above are suitable for stub files. In regular modules, 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.

关于python - 3.5 : Type Hinting and Method Overloading,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37553551/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com