Python Tuple-Enum无法使用第二个元素为0的元组的问题求助
问题
我想在国际象棋程序中用继承tuple的Enum类作为棋盘坐标,代码如下:
from enum import Enum class Pos(tuple, Enum): A1 = (0, 0) A2 = (0, 1) B1 = (1, 0) B2 = (1, 1)
但所有第二个元素为0的坐标都会触发ValueError,比如执行:
print(Pos(1, 0))
报错信息:
Traceback (most recent call last): File "C:\Users\TuffGolem\AppData\Roaming\JetBrains\PyCharmCE2023.3\scratches\scratch_6.py", line 11, in <module> print(Pos(1, 0)) ^^^^^^^^^ File "C:\Users\TuffGolem\AppData\Local\Programs\Python\Python312\Lib\enum.py", line 740, in __call__ return cls.__new__(cls, value) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\TuffGolem\AppData\Local\Programs\Python\Python312\Lib\enum.py", line 1154, in __new__ raise ve_exc ValueError: 1 is not a valid Pos
看起来程序忽略了第二个元素0,只拿第一个数字去匹配枚举值。我之前给每个坐标值加1规避,但这只是临时方案,而且因为要把元组作为Numpy数组的坐标,这个方法行不通。请问怎么正常使用第二个元素为0的坐标?
解决方案
问题根源在于Enum的构造逻辑:当继承tuple并调用Pos(1, 0)时,Python会将多个参数当作tuple的构造参数,而Enum的__call__方法会优先用第一个参数匹配枚举成员,而非将所有参数打包成完整元组匹配。
方法一:显式传入元组(Ethan Furmann方案)
给坐标元组添加额外括号,明确告诉Enum要匹配的是完整元组对象:
print(Pos((1, 0))) # 输出 Pos.B1
这种方式能让Enum正确识别你要匹配的是完整的元组值,而非拆分后的单个参数。
方法二:重写__call__方法简化调用
如果想保留Pos(1,0)的直观调用方式,可以重写Enum的__call__方法,强制将多参数打包成元组:
from enum import Enum class Pos(tuple, Enum): A1 = (0, 0) A2 = (0, 1) B1 = (1, 0) B2 = (1, 1) def __call__(cls, *args): if len(args) > 1: return cls(tuple(args)) return super().__call__(*args)
修改后直接调用Pos(1,0)就能正确返回Pos.B1,同时也兼容Pos((1,0))的调用方式。
内容的提问来源于stack exchange,提问作者Tuffi
相关产品推荐
相关产品推荐

