Pythonmatch
不仅仅是一个简单的 switch 语句。如果您只使用您认为的“变量名称”,它们实际上将是Capture Patterns。根据PEP 编号中的定义。634
除了您可能不应该将其match
用于您的用例之外,您还必须通过以下方式之一使用限定(点)名称:
#1 平面对象
statuses = object()
statuses.success = 200
status.not_found = 404
def handle(retcode):
match retcode:
case statuses.success: print("Success")
case statuses.not_found: print("Not found")
#2 面向对象编程
class StatusValues:
success = 200
not_found = 404
def handle(retcode):
match retcode:
case StatusValues.success: print("Success")
case StatusValues.not_found: print("Not found")
#3 简单的限定 locals()/globals() 访问
我开发了 match-ref 库,它允许您访问任何函数内部或外部的任何局部或全局变量,只需使用ref.
前缀即可。
from matchref import ref
import random
SUCCESS = 200
NOT_FOUND = 404
def handle(retcode):
random_code = random.randint(600,699)
match retcode:
case ref.SUCCESS: print("Success")
case ref.NOT_FOUND: print("Not found")
case ref.random_code: print("OK, you win!")
如您所见,ref
从本地和全局命名空间中自动解析变量(按此顺序)。无需额外设置。
如果您不想使用 3rd-party 库,您可以在下面看到一个稍微类似的无库版本。
#4 没有 3rd-party 库的合格 locals()/globals() 访问
locals()
并且globals()
是 Python 中的内置函数,它们返回dict
包含映射到它们各自值的所有变量名的 a。您需要能够使用点分语法访问字典的值,因为match
也不支持字典访问语法。因此,您可以编写这个简单的辅助类:
class GetAttributeDict(dict):
def __getattr__(self, name):
return self[name]
并像这样使用它:
import random
SUCCESS = 200
NOT_FOUND = 404
def handle(retcode):
random_code = random.randint(600, 699)
globs = GetAttributeDict(globals())
locs = GetAttributeDict(locals())
match retcode:
case globs.SUCCESS: print("Success")
case globs.NOT_FOUND: print("Not found")
case locs.random_code: print("OK , you win!")
#5 模块访问
鉴于您似乎打算重新使用您的状态代码(因为否则您可以将它们内联到您case
的 s 中),您可能会考虑为此使用单独的模块。
constants.py:
SUCCESS = 200
NOT_FOUND = 404
main.py
import constants
match retcode:
case constants.SUCCESS: ...
...
同样,您可能需要重新考虑是否要使用match
。