В чем разница между "cast (...)" и "... # type: ..."? - PullRequest
0 голосов
/ 25 сентября 2018

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

from typing import cast

foo = cast(str, expression)
bar = expression  # type: str

В чем разница между ними?

У меня сложилось впечатление, что иногда я используюcast работает, хотя иногда приходится использовать комментарий.Но я еще не выяснил закономерность.К сожалению, в настоящее время у меня нет примера кода, где один работает, а другой нет.

1 Ответ

0 голосов
/ 25 сентября 2018

# type: ignore означает «пожалуйста, отключите все ошибки, связанные с типом, возникающие из этой строки».

cast(TYPE, EXPR) означает «Я знаю, вы думаете, что тип EXPR X, но я хочу, чтобы выпредположим, что тип действительно TYPE, хорошо? "

Обычно вы используете # type: ignore, когда сталкиваетесь с некоторыми ограничениями проверки типов, которые вы не можете обойти.Например, предположим, что вы пытаетесь импортировать какую-то стороннюю библиотеку без заглушек или определений типов.В этом случае выполнение:

# Results in errors like"
# error: No library stub file for module 'library_with_no_hints'
import library_with_no_hints

... обычно приводит к ошибке.Но вы можете использовать # type: ignore, чтобы отключить эту ошибку:

import library_with_no_hints  # type: ignore

Обычно вы используете cast, когда у вас есть дополнительная внеполосная информация, когда средство проверки типов не знает о каком-то типеНа самом деле X - это только Y. Например:

def parse_config(assume_normalized: bool, thing: List[Union[int, str]]) -> List[int]:
    if assume_normalized:
        # The type-checker thinks that 'thing' is a List[Union[int, str]];
        # we now force it to assume it's really a List[int] instead.
        return cast(List[int], thing)
    else:
        output = []
        for item in thing:
            if isinstance(item, int):
                output.append(item)
            else:
                output.append(parse(item))
        return output

Обычно вы видите приведения, когда либо а) вы копаетесь в большом количестве кода стиля десериализации / сериализации и вам необходимо уменьшить слишком широкие типы вболее конкретные, б) вы делаете странные вещи с множественным наследованием, или в) ваш код плохо спроектирован, и вы загнали себя в угол.

Лично я почти никогда не использую приведение - я стараюсьи избегайте их, если я могу, а если нет, буду использовать как минимум проверки экземпляров и тому подобное, чтобы мой код зависал во время выполнения, если мои предположения окажутся неверными.

(я также пытаюсь игнорировать # type: ignore, но иногда они оказываются необходимым злом / могут помочь вам обойти ограничения в вашей программе проверки типов.)


Если вы планируете использовать игнорирование типов или casВ вашей кодовой базе вы также должны обратить внимание на настройку проверки типов, чтобы она предупреждала вас, когда вы используете их в ненужных местах.

Например, с помощью mypy вы можете передать --warn-unused-ignores и --warn-unused-casts flags.

...