Использовать атрибут из Необязательного параметра [Union [str, int]] в зависимости от его типа

У меня есть параметр типа: a: Optional[Union[str, int]].

Я хочу использовать некоторые атрибуты, когда это строка, и другие, когда это целое число. Например:

    if type(a) is int:
        self.a = a
    elif type(a) is str and a.endswith('some prefix'):
        self.b = a

Однако MyPy жалуется на следующее:

ошибка: элемент int of Union [str, int, None] не имеет атрибута, заканчивающегося на

ошибка: элемент None of Union [str, int, None] не имеет атрибута, заканчивающегося на

Есть ли способ заставить это работать с MyPy?


person FlyingPumba    schedule 24.09.2019    source источник


Ответы (1)


Вы должны использовать идиому isinstance(a, int) вместо type(a) is int. Если вы сделаете первое и напишете:

if isinstance(a, int):
    self.a = a
elif isinstance(a, str) and a.endswith('some_prefix'):
    self.b = a

... тогда ваш код должен аккуратно проверять типы.

Причина, по которой выполнение type(a) is int не поддерживается / скорее всего, не будет поддерживаться в ближайшее время, заключается в том, что вы в основном утверждаете, что 'a' является точным типом int и никаким другим типом.

Но на самом деле у нас нет чистого способа написать такой тип в PEP 484 - если вы скажете, что некоторая переменная 'foo' имеет тип 'Bar', вы на самом деле говорите, что 'foo' может иметь тип 'Bar' или любой подкласс 'Bar'.

person Michael0x2a    schedule 24.09.2019
comment
Разумеется, не обязательно иметь возможность выражать точность типа при поддержке type(x) is X в качестве typeguard? Mypy все же может прийти к такому же выводу, как и в случае с isinstance. - person Markus Unterwaditzer; 28.09.2019