【问题标题】:Python typing: return type with generics like Clazz[T] as in Java Clazz<T>Python 类型:返回类型与 Java Clazz<T> 中的 Clazz[T] 等泛型
【发布时间】:2020-01-11 23:52:20
【问题描述】:

所以我知道 Python 的 typing.Optional。但我自己写了粗略的PyOptional(代码here),并想将Optional[T]与我的PyOptional结合到PyOptional[T]

我目前正在使用 Python 3.7 并尝试扩展 typing.Optional

我的一些PyOptional

class PyOptional:
    T: TypeVar = TypeVar("T")

    def __init__(self, obj: T):
        self.value: Any = obj

    def get(self) -> Optional[T]:
        return self.value

    def or_else(self, default) -> T:
        return self.value or default

我想要的伪代码:

def find_user_by_id(id: int) -> PyOptional[User]:
    return PyOptional(db.find_user_by_id(id))

目标是让我的 IDE 能够检查预期的返回类型,并且仍然能够在返回的对象上调用我的方法。所以它必须符合 PEP。

【问题讨论】:

    标签: python python-3.x generics type-hinting python-typing


    【解决方案1】:

    您应该查看有关泛型的文档——具体来说,user-defined generics。 mypy 文档也有一个完整的overview of generics,可供参考。

    在这种特殊情况下,您希望通过添加Generic[T] 作为类基来使整个类通用。仅在单个函数签名中使用 T 将使每个 individual 函数通用,而不是整个类:

    from typing import TypeVar, Generic, Optional
    
    T = TypeVar("T")
    
    class PyOptional(Generic[T]):
        def __init__(self, obj: Optional[T]) -> None:
            self.value = obj
    
        def get(self) -> Optional[T]:
            return self.value
    
        def or_else(self, default: T) -> T:
            return self.value or default
    

    一些补充说明:

    1. 不要为任何 TypeVar 变量添加注释。在这里,T 是一种元类型构造,用作“洞”/可以表示任意数量的类型。所以,给它分配一个固定的类型并没有什么意义,而且会混淆类型检查器。

    2. 永远不要在任何给定的签名中只使用一次 TypeVar - 使用 TypeVars 的全部意义在于您可以声明两个或多个类型总是相同的。

      请注意,上面固定的 PyOptional 类也遵守此规则。例如,以get 为例。现在我们使整个类成为通用的,这个函数的类型签名现在基本上类似于def get(self: PyOptional[T]) -&gt; Optional[T]。之前,更像是def get(self: PyOptional) -&gt; Optional[T]

    3. 为了使您的类有意义,您可能希望您的构造函数接受Optional[T] 而不仅仅是T

    4. 制作self.value Any 可能是不必要的/不必要地太模糊了。我们可以省略类型提示,现在它的推断类型将是Optional[T]

    5. 如果您想更彻底地检查您的课程是否符合 PEP 484 并且可能会被 PyCharm 等 IDE 理解,请考虑通过 mypy(PEP 484)使用您的课程对您的课程 + 一些代码进行类型检查类型检查器。

      这并不能保证您的 IDE 将完全理解您的类(因为它可能无法完全实现有关 PEP 484 的所有内容/您可能会在 mypy 或您的 IDE 中遇到错误),但它应该可以帮助您非常接近.

    【讨论】:

    • 谢谢!这正是我想要的,我可以确认它有效!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    相关资源
    最近更新 更多