首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回python中用户制造的容器的切片类型。

返回python中用户制造的容器的切片类型。
EN

Stack Overflow用户
提问于 2021-09-09 06:31:40
回答 1查看 154关注 0票数 1

我正在创建一个自定义容器,它在切片时返回自身的一个实例:

代码语言:javascript
复制
from typing import Union, List

class CustomContainer:
    def __init__(self, values: List[int]):
        self.values = values

    def __getitem__(self, item: Union[int, slice]) -> Union[int, CustomContainer]:
        if isinstance(item, slice):
            return CustomContainer(self.values[item])
        return self.values[item]

这是可行的,但附带以下问题:

代码语言:javascript
复制
a = CustomContainer([1, 2])
b = a[0]  # is always int, but recognized as both int and CustomContainer
c = a[:]  # is always CustomContainer, but recognized as both int and CustomContainer

# Non-scalable solution: Forced type hint
d: int = a[0]
e: CustomContainer = a[:]

如果我将__getitem__的返回类型更改为int (我最初的方法),那么a[0]正确地显示了int类型,但是a[:]被认为是list而不是CustomContainer。据我所知,在python2中曾经有一个函数来定义如何创建切片,但它在python3中被删除了。

是否有一种方法可以在每次使用我的容器时,给出正确的类型提示,而不必强制类型提示?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-09 07:32:18

您希望使用typing.overload,它允许您使用类型检查器注册一个函数的多个不同签名。使用@overload修饰的函数在运行时被忽略,因此通常只需使用文字省略号...pass或docstring来填充正文。这也意味着您必须保留至少一个没有使用@overload修饰的函数版本,这将是运行时使用的实际函数。

如果您查看typeshed (大多数主要类型检查器用于检查标准库的存根文件的存储库),您会发现这是它们在自定义容器(如collections.UserList )中注释__getitem__方法的技术。在您的例子中,您可以这样注释您的方法:

代码语言:javascript
复制
from typing import overload, Union, List

class CustomContainer:
    def __init__(self, values: List[int]):
        self.values = values
        
    @overload
    def __getitem__(self, item: int) -> int:
        """Signature when the function is passed an int"""
        
    @overload
    def __getitem__(self, item: slice) -> CustomContainer:
        """Signature when the function is passed a slice"""

    def __getitem__(self, item: Union[int, slice]) -> Union[int, CustomContainer]:
        """Actual runtime implementation"""

        if isinstance(item, slice):
            return CustomContainer(self.values[item])
        return self.values[item]

a = CustomContainer([1, 2])
b = a[0]
c = a[:]

reveal_type(b)
reveal_type(c)

运行它通过MyPy,它将告诉我们:

代码语言:javascript
复制
main.py:24: note: Revealed type is "builtins.int"
main.py:25: note: Revealed type is "__main__.CustomContainer"

再读

@overload的类型文档可以找到这里

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69113269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档