Захват делает оставшиеся шаблоны недоступными
Почему этот код не работает:
OKAY = 200
NOT_FOUND = 404
INTERNAL_SERVER_ERROR = 500
match status:
case OKAY:
print('It worked')
case NOT_FOUND:
print('Unknown')
case INTERNAL_SERVER_ERROR:
print('Out of service')
case _:
print('Unknown code')
Он генерирует это сообщение об ошибке:
File "/Users/development/Documents/handler.py", line 66
case OKAY:
^^^^
SyntaxError: name capture 'OKAY' makes remaining patterns unreachable
Что означает это сообщение об ошибке и как исправить код, чтобы он заработал?
2 ответа
Причина проблемы
Имя переменной в предложении case рассматривается как шаблон захвата имени .
Он всегда спичек и пытается сделать задание к имени переменной. Это почти наверняка не то, что было задумано .
Потому что выигрывает первый соответствующий случай и потому что
case OKAY
всегда совпадает, другие предложения case никогда не проверяются.
Это объясняет сообщение об ошибке:
SyntaxError: name capture 'OKAY' makes remaining patterns unreachable
Ключ к решению проблемы
Нам нужно заменить шаблон захвата имени шаблоном без захвата, например который использует оператор для поиска атрибутов. Точка - это ключ к совпадению с шаблоном без захвата.
Есть много способов добиться этого. Один из них - поместить имена в пространство имен класса:
class ResponseCode:
OKAY = 200
NOT_FOUND = 404
INTERNAL_SERVER_ERROR = 500
Сейчас,
case ResponseCode.NOT_FOUND: ...
является шаблоном значения (из-за точки) и не захватывается.
Другой способ добиться того же эффекта - переместить константы в их собственный модуль и ссылаться на них с помощью точки:
import response_code
match status:
case response_code.OKAY: ...
case response_code.NOT_FOUND: ...
case response_code.INTERNAL_SERVER_ERROR: ...
Помимо создания класса или модуля, также можно создать целочисленное перечисление для того же эффекта:
from enum import IntEnum
class ResponseCode(IntEnum):
OKAY = 200
NOT_FOUND = 404
INTERNAL_SERVER_ERROR = 500
Для кодов ответа HTTP целочисленное перечисление уже создано для вас в классе HTTPStatus из стандартной библиотеки.
Пример решения
Вот отработанное решение исходной проблемы. Наличие
.
поиск по атрибуту enum является ключом к сопоставлению, и регистр распознает это как шаблоном значения,шаблон значения :
from http import HTTPStatus
status = 404
match status:
case HTTPStatus.OK:
print('It worked')
case HTTPStatus.NOT_FOUND:
print('Unknown')
case HTTPStatus.INTERNAL_SERVER_ERROR:
print('Out of service')
case _:
print('Unknown code')
Мой совет: если вы используете вопрос, вам нужно написать такой сценарий.
match (your variable)
case Hello:
print('Hi back!')
к:
match (your variable)
case 'Hello':
print('Hi back!')