从类型到实例化对象的 Python 通用类型提示
Posted
技术标签:
【中文标题】从类型到实例化对象的 Python 通用类型提示【英文标题】:Python Generic typehint going from type to instanciated object 【发布时间】:2021-09-28 20:19:02 【问题描述】:我的 IDE 自动完成目前存在一些问题,因为它无法判断返回类型是什么等。
我有一个单例元类,覆盖类似于此的 __call__
方法:
SingletonTypes = typing.TypeVar("SingletonTypes")
class Singleton(ABCMeta):
def __call__(cls: SingletonTypes, environment: str = None, *args, **kwargs) -> SingletonTypes:
/* code here, will return an instanciated copy of cls */
return super(Singleton, cls).__call__()
我的问题是如果我有通用类型提示,显然 cls 是一种类型,它会返回对象。我不确定如何指定 typehints 来表明这一点,而没有 python 会感到困惑。
如果我尝试将type(SingletonTypes)
添加到 cls 类型提示中,那么它不会提出任何建议,因为 SingletonType 之间没有一致性。不太确定如何进行,如果能正常使用自动完成功能会很好。
【问题讨论】:
【参考方案1】:你试过了吗:
def __call__(cls: Singleton, environment: str = None, *args, **kwargs) -> SingletonTypes:
从技术上讲,这是正确的:cls 是“Singleton”的一个实例,它是您的单例类的元类。但我不确定围绕注释的工具对元类的工作方式有多了解——在某些方面,用于类型提示和注释的工具感觉与语言的实际工作方式完全脱节。
如果这不起作用,您应该满足于使用单例而不求助于元类,因为无论如何这都是多余的。除非您需要一个只运行一次的 __init__
方法,并且不能在 __new__
中,否则您只需将在元类中的相同逻辑添加到 __call__
到类上的 __new__
,或在基类本身上。由于这种机制将使用简单的继承,类型提示机制应该可以正常工作,不需要特殊的注释:
class SingletonBase:
def __new__(cls, *args, **kw):
if "_instance" in cls.__dict__:
return cls._instance # NB: this will still trigger a call to __init__ in subclasses
instance = super().__new__(cls, *args, **kw)
cls._instance= instance
return instance
(我认为在这种情况下,类型提示机制甚至可以在没有显式注释的情况下找到自己的方式,因为__new__
的角色在语言语义中得到了很好的定义)
【讨论】:
我刚刚试了一下,又不行了。我认为问题在于 SingletonTypes 是泛型的,python 没有关于实际输出的信息,因为它通常来自泛型参数。以上是关于从类型到实例化对象的 Python 通用类型提示的主要内容,如果未能解决你的问题,请参考以下文章