Как вы говорите, вам нужно показать код. : -)
Ошибка переполнения стека обычно происходит, когда ваша функция вызывает слишком много гнезд. См. Поток «Переполнение потока стека» для некоторых примеров того, как это происходит (хотя в случае этого вопроса ответы преднамеренно вызывают переполнение стека).
Мы можем написать функцию полезности, которая внутренне обрабатывает None
-изложенные случаи и вызывает исключение / возвращает некоторое фиктивное значение данного типа:
from xml.etree.ElementTree import Element
def find(element: Element,
tag: str) -> Element:
result = element.find(tag)
assert result is not None, ('No tag "{tag}" found '
'in element "{element}".'
.format(tag=tag,
element=element))
return result
преимущество утверждений (по сравнению с повышением исключения вручную) заключается в том, что они могут быть отключены , но если вы работаете с некоторыми данными по отдельности, я рекомендую поднять исключение, например
if result is None:
raise LookupError('No tag "{tag}" found '
'in element "{element}".'
.format(tag=tag,
element=element))
Я использую аннотации типов, так как это помогает IDE, и это также экономит много времени при чтении API, но я не являюсь пользователем mypy, потому что мне не нравится идея проверять все, как в этом случае: если функция пользователя передает мусор, то это его вина, мы должны позволить ему сделать это вместо того, чтобы что-то писать о «у вас есть объединение типов и не обрабатывать случаи с некоторыми из них», EAFP после всех .
Mypy не использует __annotations__
, то есть конструкцию времени выполнения. Анализ Mypy полностью статичен.
«встроенные» типы (аналогичные типы из стандартной библиотеки) получены из typeshed . Если вы хотите изменить эти типы для своих целей, вы можете (хотя я бы сильно отговорил его как решение вашей проблемы). Чтобы использовать пользовательский тип с mypy, вы можете сделать mypy --custom-typeshed-dir=/path/to/my/typeshed ...
, а mypy будет использовать ваш модифицированный файл.
. Более эргономичное решение должно было бы сделать, как предлагает Азат, и написать обертку, которая перемещает сужение типа до функция полезности, так что локальная читаемость не страдает и вы сохраняете безопасность типов.
Я думаю, что здесь есть три разных варианта.
--no-strict-optional
, который сделает mypy обрабатывать значения типа «Нет» как член всех типов. Или, говоря иначе, если вы знакомы с такими языками, как Java, законно делать такие вещи, как это: String myString = null;
Передача в флаг --no-strict-optional
в mypy заставит его начать принимать код, как указано выше. Это, очевидно, означает, что ваш код будет меньше типов: mypy больше не способен обнаруживать потенциальные исключения «null pointer». Чтобы облегчить это, вы можете попробовать отключить строго-необязательный локально , а не глобально , создав конфигурационный файл mypy . В двух словах вы создадите конфигурационный файл, который выглядит примерно так: [mypy]
# Global options can go here. We'll leave this empty since we don't
# want to change any of the defaults.
[mypy-mycodebase.my.xml.processing.module]
# We weaken mypy in *just* this module
strict_optional = False
root
быть типа «Любой» и отправиться в город. Затем, когда вы собираете полезные данные из своего XML, выполните все необходимые проверки времени выполнения, чтобы проверить ваши данные и создать объекты (typesafe!) Для хранения соответствующей информации. (Конечно, вы можете продолжать использовать статическую типизацию для остальной части вашего кода). Наблюдение здесь заключается в том, что любой вход во время выполнения будет по своей сути динамическим: пользователь всегда может пройти в некорректном XML, данные могут быть структурированы неправильно и т. Д. Единственный реальный способ проверки этих проблем - использовать проверки времени выполнения: проверка статического типа не поможет. Итак, если проверка статического типа обеспечивает минимальное значение в определенной области кода, зачем продолжать использовать ее там? Конечно, у этой тактики есть несколько недостатков. В частности, mypy не сможет обнаружить вопиющие злоупотребления API ElementTree, вам нужно быть достаточно внимательным к проверкам времени выполнения, чтобы убедиться, что плохие данные не ползут в регионы с проверкой типов вашего кода и т. Д. .