Есть ли эквивалент восклицательного знака Typescript в Python? - PullRequest
0 голосов
/ 21 июня 2020

Я начинаю использовать подсказки типа в Python. У меня есть следующая функция:

def func(arg: Optional[str]):
    # ...
    # make sure arg is a string and not None
    do_something(arg)  # do_something expects a string

Вызов do_something может быть достигнут только в том случае, если arg действительно является строкой, а не None, но mypy не понимает это самостоятельно (это не mypy проблема, он не может все понять). Таким образом, mypy отмечает вызов do_something, потому что arg может быть None

В Typescript аналогичная ситуация может быть обработана с помощью arg! - восклицательный знак сообщает анализатору stati c, что arg не неопределенный. Есть ли что-то подобное в Python?

Ответы [ 3 ]

2 голосов
/ 21 июня 2020

Mypy не должен ничего отмечать, если ваш logi c содержит:

if arg is None:
    return None

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

assert x is not None
1 голос
/ 21 июня 2020

Между TypeScript и Python с mypy есть пара фундаментальных отличий. Это ближе к тому, как работает ECMAScript с Google Closure Compiler , чем как работает TypeScript. Или, как современные IDE используют подсказки типов в комментариях к документации.

Во-первых, TypeScript имеет систему типов и правила набора. Python не имеет не системы типов или правил набора. Python только имеет синтаксис для подсказок типа. Однако сам Python ничего не делает с этими подсказками типа. Это оставлено сторонним инструментам. Это имеет некоторые преимущества и некоторые недостатки. Самым большим преимуществом является то, что вы можете выбрать инструмент, наиболее подходящий для вашей конкретной области применения. Самый большой недостаток заключается в том, что когда вы записываете подсказку типа, вы на самом деле не знаете, что она означает… потому что она не имеет значения. Значение присваивается внешним сторонним инструментом.

Другими словами: Python подсказки типов не имеют определенной семантики .

Второе отличие состоит в том, что TypeScript имеет отдельный язык шрифтов. Типовой язык Python вместо Python. Это означает, что подсказка типа должна быть синтаксически допустимым выражением Python. Фактически, подсказки типа оцениваются во время выполнения, поэтому они должны быть не только синтаксически действительными Python, но и семантически действительными Python; они должны быть исполняемыми без ошибок или исключений, даже если вы никогда не используете их во время выполнения и используете их только для проверки типов stati c, например, с помощью mypy. (Это основная причина для модуля typing: предоставить функции и объекты, позволяющие преобразовать синтаксис, который вы хотите записать (например, универсальные шаблоны), в допустимые выражения времени выполнения.)

Другими словами: Python подсказки типа не имеют отдельного синтаксиса , это просто Python выражения.

Итак, первое, что это говорит нам, это то, что какое бы потенциальное решение вы ни придумали, оно должно быть синтаксически и семантически действительным Python. arg! синтаксически неверно Python. Таким образом, точный эквивалент синтаксиса TypeScript невозможен.

Итак, мы должны проверить, можем ли мы найти эквивалент semanti c с другим синтаксисом. Возможные места, где мы можем его найти:

Глядя на эти три , мы обнаруживаем, что ничего не находим. Это не доказательство того, что чего-то подобного не существует (отсутствие доказательств не свидетельствует об отсутствии), но это хороший показатель.

Mypy поддерживает только эквивалент TypeScript Тип Guard :

if arg is None:
    pass
else:
    # mypy knows that `arg` is a `str` here

if arg is not None:
    # mypy knows that `arg` is a `str` here

if not arg:
    pass
else:
    # mypy knows that `arg` is a `str` here

if arg:
    # mypy knows that `arg` is a `str` here

В случае, если вы не можете предоставить такой тип защиты, или вы на 100% знаете, что arg не может быть None в в этой точке, ни при каких обстоятельствах, НИКОГДА, вы можете предоставить утверждение типа:

assert arg is not None
# mypy knows that `arg` is a `str` here

Утверждение типа также даст mypy знать, что arg не может быть None после этой точки. Это явно задокументировано в документации mypy.

Это может быть семантически ближе всего к оператору типа TypeScript !. Фактически, оператор ! на самом деле не что иное, как утверждение: «Эй, проверка типов, поверь мне, я знаю кое-что, чего ты не знаешь». Это в точности то же самое, что и утверждение Python.

0 голосов
/ 21 июня 2020

В python нет нулевой безопасности.

Лучшее, что вы можете сделать, это:

if arg is not None:
    do_something(arg)

Или, если вы хотите вызвать исключение:

if arg is None:
    raise Exception("arg == none")

do_something(arg) # arg will not be None

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

def x(y: int):
    return y

x("hello")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...