Python键入列表的子类 [英] Python typing for a subclass of list

查看:121
本文介绍了Python键入列表的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够定义list子类的内容.该类如下所示.

I want to be able to define what the contents of a subclass of list have to be. The class would look like the following.

class A(list):
   def __init__(self):
      list.__init__(self)

我想包括键入内容,以便进行以下操作.

I want to include typing such that the following would happen.

import typing

class A(list: typing.List[str]):  # Maybe something like this
   def __init__(self):
      list.__init__(self)

>> a = A()
>> a.append("a")  # No typing error
>> a.append(1)  # Typing error

推荐答案

typing方便地提供了collections.MutableSequence的通用版本,因此具有以下作用:

typing conveniently provides a generic version of collections.MutableSequence, so something to the effect of:

import typing

T = typing.TypeVar('T')
class HomogeneousList(typing.MutableSequence[T]):
    def __init__(self, iterable: typing.Iterable[T]=()) -> None:
        self._data: typing.List[T]  = []
        self._data.extend(iterable)

    @typing.overload
    def __getitem__(self, index: int) -> T: ...
    @typing.overload
    def __getitem__(self, index: slice) -> HomogeneousList[T]: ...
    def __getitem__(self, index):
        return self._data[index]

    @typing.overload
    def __setitem__(self, index: int,  item: T) -> None: ...
    @typing.overload
    def __setitem__(self, index: slice, item: typing.Iterable[T]) -> None: ...
    def __setitem__(self, index, item):
        self._data[index] = item

    def __delitem__(self, index: typing.Union[int, slice]) -> None:
        del self._data[index]

    def __len__(self) -> int:
        return len(self._data)

    def insert(self, index: int, item: T) -> None:
        self._data.insert(index, item)


string_list = HomogeneousList[str]()
string_list.append('foo')
string_list.append(42)


int_list = HomogeneousList[int]()
int_list.append(42)
int_list.append('foo')

现在,mypy出现以下错误:

test.py:36: error: Argument 1 to "append" of "MutableSequence" has incompatible type "int"; expected "str"
test.py:41: error: Argument 1 to "append" of "MutableSequence" has incompatible type "str"; expected "int"

键入__getitem__等有一些棘手的方面,因为它们也接受slice对象,但并不可怕.

There is some tricky aspects of typing __getitem__ etc because they accept slice objects as well, but not terrible.

请注意,这很有用,因为如果您尝试这样做:

Note, this is useful, because if you just try to do:

class HomogeneousList(collections.abc.MutableSequence, typing.Generic[T]):
    ....

至少,MyPy不会引发附加错误. AFAIKT,您必须明确添加:'

MyPy, at least, doesn't throw an error for append. AFAIKT you'd have to explicitly add:'

def append(self, item: T) -> None:
    self._data.append(item)

首先删除了collections.abc.MutableSequence的许多实用程序.无论如何,幸运的是,键入提供了所有这些的通用版本!

Which sort of removes a lot of the utility of collections.abc.MutableSequence to begin with. Anyway, thankfully, typing provides generic versions of all of these out of the box!

请注意,您可以像我展示的那样通用使用它们,但是您也可以执行以下操作:

Note, you can use these generically, like I've show, but you can also do something like:

class StringList(HomogeneousList[str]):
    pass

mylist = StringList([1,2,3]) # mypy error
mylist = StringList('abc') # no error

mylist.append('foo') # no error
mylist.append(42) # mypy error

这篇关于Python键入列表的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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