【问题标题】:Python Generic typehint going from type to instanciated object从类型到实例化对象的 Python 通用类型提示
【发布时间】: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 之间没有一致性。不太确定如何进行,如果能正常使用自动完成功能会很好。

【问题讨论】:

    标签: python type-hinting metaclass


    【解决方案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 没有关于实际输出的信息,因为它通常来自泛型参数。
    猜你喜欢
    • 2022-11-02
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    相关资源
    最近更新 更多