Заставьте mypy распознать тип списка - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть такой код

from typing import Union, List

class Player:
    number: str

def func(things: List[Union[Player, str]]):
    if isinstance(things[0], Player):
        print(" ".join(p.number for p in things))
    else:
        print(" ".join(things))

Mypy выделяет p.number, а things в блоке else дает мне эту ошибку:

[mypy error] [E] Item "str" of "Union[Player, str]" has no attribute "number"

Я также пытался

def func2(things: List[Union[Player, str]]):
    if all(isinstance(thing, Player) for thing in things):
        print(" ".join(p.number for p in things))
    elif all(isinstance(thing, str) for thing in things):
        print(" ".join(things))

Но я получаю ту же ошибку. Как заставить mypy распознать, что я утверждаю, что каждый элемент списка имеет определенный c тип?

1 Ответ

0 голосов
/ 19 апреля 2020

Вы не хотите иметь «список (игроков или строк)», хотите «(список игроков) или (список строк)»:

def func(things: Union[List[Player], List[str]]):
    if isinstance(things[0], Player):
        things = cast(List[Player], things)
        print(" ".join(p.number for p in things))
    else:
        things = cast(List[str], things)
        print(" ".join(things))

Я надеваю не думаю, что есть более изящный способ заставить проверку типов работать, чем cast; mypy не кажется достаточно умным, чтобы вывести тип things на основе только вашей проверки things[0], и вы не можете выполнить isinstance(things, List[Player]).

...