Несовместимые типы в присваивании mypy - PullRequest
0 голосов
/ 15 октября 2018

У меня есть следующая функция, которая получает строку вида 'a-02/b-03/foobarbaz_c-04', которая извлекает цифры после a , b и c ,Проблема в том, что для моего случая использования входные строки могут не содержать c , так что не будет никаких цифр для извлечения.

Вот код:

from typing import Tuple, Optional


def regex_a_b_c(name: str) -> Tuple[int, int, Optional[int]]:
        a_b_info = re.search('a-(\d\d)/b-(\d\d)/', name)
        a, b = [int(a_b_info.group(x)) for x in range(1, 3)]
        c_info = re.search('c-(\d\d)', name)
        if c_info:
            c = int(c_info.group(1))
        else:
            c = None   
        return a, b, c

У меня проблема в том, что, несмотря на попытки прояснить, что последний аргумент возврата является Optional[int], я не могу получить свой линтерчтобы перестать жаловаться на переменную c.

В строке c =None появляется предупреждение о том, что

Несовместимые типы в присваивании (выражение имеет тип None, переменная имеет тип int)

.Как я могу решить проблему?

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Когда вы используете переменную в первый раз, mypy по существу выведет ее тип на основе самого первого присваивания, которое она видит.

Таким образом, в этом случае строка c = int(_info.group(1)) появляется первой, поэтому mypy решаетчто тип должен быть int.Затем он жалуется, когда видит c = None.

. Один из способов обойти это ограничение - просто объявить переменную с ожидаемым типом.Если вы используете Python 3.6+ и можете использовать переменные аннотации, вы можете сделать это следующим образом:

c: Optional[int]
if c_info:
    c = int(c_info.group(1))
else:
    c = None

Или, возможно, более кратко, например:

c: Optional[int] = None
if c_info:
    c = int(c_info.group(1))

Если вам нужноПоддерживая более старые версии Python, вы можете аннотировать тип, используя синтаксис на основе комментариев, например:

c = None  # type: Optional[int]
if c_info:
    c = int(c_info.group(1))

Предложение rje сделать:

if c_info:
    c = int(c_info.group(1))
    return a, b, c
else:
    return a, b, None

... такжеразумный.

0 голосов
/ 15 октября 2018

Вы должны вернуть либо кортеж a,b,c, либо кортеж a,b без указания c.Таким образом, вам вообще не нужно присваивать значение N для c.

if c_info:
    c = int(c_info.group(1))
    return a, b, c
else:
    return a, b
...