如何为子类实例列表进行类型注释,例如连接两个列表?

问题描述 投票:0回答:2

我想迭代

List[A]
List[Subclass of A]
并执行相同的循环。我认为做到这一点的最好方法是将两个列表连接起来。然而,mypy 对此并不高兴。

我怎样才能将两者连接起来并让我的朋友开心?

目前,我做

# type: ignore[operator]
。如果可能的话,我想避免这种情况。

MVCE

# Core Library modules
from typing import Iterable

# Third party modules
from pydantic import BaseModel


class Animal(BaseModel):
    height: float
    weight: float


class Cat(Animal):
    lives: int = 7


cats = [Cat(height=1, weight=2, lives=7), Cat(height=3, weight=2, lives=1)]
animals = [Animal(height=9, weight=9)]

combined: Iterable[Animal] = cats + animals

for animal in combined:
    print(animal)

给予

$ mypy untitled.py
untitled.py:20: error: Unsupported operand types for + ("List[Cat]" and "List[Animal]")
Found 1 error in 1 file (checked 1 source file)
python mypy python-typing
2个回答
2
投票

出现这种情况是因为

list
不变(提供了一个说明性示例)。

我可以提供两种解决方案:

  1. 将两个列表显式定义为
    List[Animal]
    以成功串联:
cats: List[Animal] = [Cat(height=1, weight=2, lives=7), Cat(height=3, weight=2, lives=1)]
animals: List[Animal] = [Animal(height=9, weight=9)]
combined: Iterable[Animal] = cats + animals

for animal in combined:
    print(animal)
  1. 使用itertools.chain进行连续迭代:
cats = [Cat(height=1, weight=2, lives=7), Cat(height=3, weight=2, lives=1)]
animals = [Animal(height=9, weight=9)]

for animal in itertools.chain(cats, animals):
    print(animal)

0
投票

如果不介意的话,请将

List
更改为
Sequence

from typing import Sequence

class Base: pass

class Derived(Base): pass

ds: Sequence[Derived] = [Derived()]
bs: Sequence[Base] = ds

你会得到

$ mypy temp.py
Success: no issues found in 1 source file
© www.soinside.com 2019 - 2024. All rights reserved.