具有相同类型的所有元素的子类 Python 列表

Subclass Python list with all elements of the same type

我正在寻找一种方法来创建 list 的子class,其中所有元素都属于同一类型。我不需要完全通用的实现,.

我想要的是大致等同于以下代码的东西(使用 typing):

class NumberParty(list[int]):
    def __str__(self) -> str:
        "".join([str(x) for x in self])

    def total(self) -> int:
        return sum(self)

我想要这个class而不是使用List[int]注解的原因是我在多个地方使用了上面描述的__str__方法并且想消除复制的代码行。


作为奖励问题,在类似于以下代码的内容中重载 __init__ 是否明智?

__init__(self, *numbers: int):
    self = numbers
__init__(self, nums: Iterable[int]):
    self = list(nums)

第一种方法是直接创建一个新的 NumberParty 实例,而第二种方法是从现有列表或整数集创建一个实例。

除非我误解了你的问题,否则就这样做:

from typing import List

class NumberParty(List[int]):
    def __str__(self) -> str:
        return "".join([str(x) for x in self])

    def total(self) -> int:
        return sum(self)

...应该可以正常工作。

请注意,从 List[int] 继承与从 list 继承基本相同——唯一的区别是类型检查器将了解您的自定义 class 应该包含的内容,并且验证您是否以类型安全的方式使用 append(...) 等方法。

但是,在运行时没有区别,您仍然可以自由地忽略类型检查器并附加 strs 或其他任何东西,就像 Python 允许您将 strs 附加到注释为的常规列表一样类型列表 [int].

并且因为这个 class 是 List[int] 的子类型,像下面这样的代码片段应该进行类型检查:

def expect_list(x: List[int]) -> None: pass

def expect_number_party(x: NumberParty) -> None: pass

n = NumberParty()

# Both type checks
expect_list(n)
expect_number_party(n)

关于您关于覆盖 __init__ 的问题——如果您决定采用该路线以确保正确设置 class,则需要调用超级构造函数。

想法

我不知道。如果我明白你问的是什么

我从你的问题中得到的是:你想要一个数组 正如 Marcos 在评论中所说。

并且仅仅为了一个数组而将整个 NumPy 库添加到您的依赖项中是多余的。

你需要的是制作一个类似列表的对象,它使用列表来存储东西和 和一个 public API 和几个 'magic functions' 使它像列表一样工作(带有你想要的过滤器)。

代码

from typing import Iterable, optional


class NumberParty:
    def __init__(self, iterable: optional[Iterable] = ()):
        self._inner = [].extend(iterable)


    def __getitem__(self, item):
        return self._inner[item]


    def __setitem__(self, key, value):
        if not isinstance(value, int):
            raise ValueError("NumberParty only accepts integers")
        self._inner[key] = value


    def __len__(self):
        return len(self._inner)


    def __iter__(self):
        return iter(self._inner)


    def append(self, i: int) -> None:
        if not isinstance(i, int):
            raise ValueError("NumberParty only accepts integers")
        self._inner.append(i)


    def insert(self, index: int, i: int) -> None:
        if not isinstance(i, int):
            raise ValueError("NumberParty only accepts integers")

        self.inner[index] = i


    def extend(self, __iterable: Iterable[int]) -> None:
        # Itering through it to check every value
        for i in __iterable:
            if not isinstance(i, int):
                raise ValueError("NumberParty only accepts integers")
            self.append(i)

请注意此NumberParty不完整 操作如: + - / % * += -= /= %= *= 未实现但已在原始列表中实现(加上此处未实现的几个 public 函数)

完成此 NumberParty 对象的提示

这个 Class 可以是 list 对象的包装器。等你来完成 ;)

如果您只是想让类型检查器显示警告 有效。