捕获使剩余模式无法访问

问题描述

@H_404_0@为什么这段代码会失败:

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')
@H_404_0@它生成错误消息:

  File "/Users/development/Documents/handler.py",line 66
    case OKAY:
         ^^^^
SyntaxError: name capture 'OKAY' makes remaining patterns unreachable
@H_404_0@该错误消息是什么意思,我该如何修复代码以使其正常工作?

解决方法

问题原因

case 子句中的变量名被视为 name capture pattern

总是匹配并尝试对变量名称进行赋值。这几乎可以肯定不是预期的

因为第一个匹配的 case 获胜并且因为 case OKAY 总是匹配,所以永远不会检查其他 case 子句。

这解释了错误消息:

SyntaxError: name capture 'OKAY' makes remaining patterns unreachable

解决问题的关键

我们需要将名称捕获模式替换为非捕获模式,例如使用 . 运算符进行属性查找的 value pattern。点是匹配非捕获模式的关键。

有很多方法可以实现这一点。一种是将名称放在类命名空间中:

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: ...

除了创建类或模块之外,还可以创建一个 integer enumeration 以达到相同的效果:

from enum import IntEnum

class ResponseCode(IntEnum):
    OKAY = 200
    NOT_FOUND = 404
    INTERNAL_SERVER_ERROR = 500

对于 HTTP 响应代码,已经在标准库中的 HTTPStatus 类中为您创建了一个整数枚举。

示例解决方案

这是原始问题的解决方案。用于枚举属性查找的 . 的存在是 matchcase 将其识别为 value pattern 的关键:

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')