Python类型:返回类型与Java Clazz< T>中的Clazz [T]之类的泛型 [英] Python typing: return type with generics like Clazz[T] as in Java Clazz<T>

查看:410
本文介绍了Python类型:返回类型与Java Clazz< T>中的Clazz [T]之类的泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我知道python的类型.可选.但是我写了我自己的原始PyOptional( https://github.com/felixhertrampf/PyOptional/blob/master/PyOptional.py ),并希望将Optional [T]与我的PyOptional合并为PyOptional [T].

So I am aware of pythons typing.Optional. But I wrote my own crude PyOptional (https://github.com/felixhertrampf/PyOptional/blob/master/PyOptional.py) and would like to combine Optional[T] with my PyOptional to PyOptional[T].

我目前正在使用Python 3.7,并尝试扩展键入.

I am currently using Python 3.7 and tried extending typing.Optional.

我的一些PyOptional

Some of my 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.

The goal is for my IDE to be able to check what return type to expect and still be able to invoke my methods on the returned object. So it would have to be PEP compliant.

推荐答案

您应该阅读有关泛型的文档-具体来说,泛型概述,可用于参考

You should review the documentation on generics -- specifically, user-defined generics. The mypy docs also have a thorough overview of generics that can be useful to reference.

在这种特殊情况下,您想通过添加Generic[T]作为类库来使整个类通用.仅在各个函数签名中使用T会使每个 individual 函数通用,而不是整个类:

In this particular case, you want to make the entire class generic by adding in a Generic[T] as a class base. Just using T in the individual function signatures will make each individual function generic, but not the class as a whole:

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是一种元类型构造,可以充当空洞"/可以表示任意数量的类型.因此,将其分配为固定类型实际上没有任何意义,并且会混淆类型检查器.

  1. Don't add an annotation for any TypeVar variable. Here, T is a sort of meta-type construct that serves as "hole"/can represent any number of types. So, assigning it a fixed type doesn't really make sense, and will confuse type checkers.

在任何给定的签名中都不要仅使用TypeVar一次-使用TypeVars的要点是,这样您就可以声明两个或多个类型总是相同的.

Never use a TypeVar only once in any given signature -- the whole point of using TypeVars is so that you can declare two or more types are always going to be the same.

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

Note that the fixed PyOptional class above also obeys this rule. For example, take get. Now that we made the whole class generic, the type signature for this function is now basically something like def get(self: PyOptional[T]) -> Optional[T]. Before, it was more like def get(self: PyOptional) -> Optional[T].

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

For your class to make sense, you probably want your constructor to accept an Optional[T] instead of just T.

进行self.value任何事情可能都是不必要的/太含糊了.我们可以省略类型提示,现在它具有推断的类型Optional[T].

Making self.value Any is probably unnecessary/is unnecessarily too vague. We can leave off the type hint, and now it'll have an inferred type of Optional[T].

如果您想更彻底地检查您的班级是否符合PEP 484,并可能被诸如PyCharm之类的IDE理解,请考虑通过 mypy .

If you want to more thoroughly check whether or not your class is PEP 484 compliant and will likely be understood by IDEs such as PyCharm, consider type-checking your class + some code using your class via mypy, a PEP 484 type checker.

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

This won't guarantee that your IDE will fully understand your class (since it might not fully implement everything about PEP 484/you might run into a bug in either mypy or your IDE), but it should help you get pretty close.

这篇关于Python类型:返回类型与Java Clazz< T>中的Clazz [T]之类的泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆