我正在Python中实现波函数折叠算法,并且每个图块都有图块和规则集。为了存储规则集,我有一个 createAll 函数,它是一个图块及其规则的字典。
这是 createAll 函数(在 TileRuleSetFactory 内部):
@staticmethod
def createAll() -> dict[Tile, TileRuleSet]:
if (TileRuleSetFactory._allRuleSets != None):
return TileRuleSetFactory._allRuleSets
ruleSets: dict[Tile, TileRuleSet] = {}
ruleSets[TileFactory.createBlank()] = TileRuleSetFactory.createBlank()
print(ruleSets)
print(ruleSets[TileFactory.createBlank()])
ruleSets[TileFactory.createUp()] = TileRuleSetFactory.createUp()
ruleSets[TileFactory.createRight()] = TileRuleSetFactory.createRight()
ruleSets[TileFactory.createDown()] = TileRuleSetFactory.createDown()
ruleSets[TileFactory.createLeft()] = TileRuleSetFactory.createLeft()
TileRuleSetFactory._allRuleSets = ruleSets
return ruleSets
TileFactory 类:
class TileFactory:
#region Tile IDs
MAX_ID = 4
BLANK_ID: int = 0
UP_ID: int = 1
RIGHT_ID: int = 2
DOWN_ID: int = 3
LEFT_ID: int = 4
#endregion
# for flyweight pattern
_createdTiles: dict[int, Tile] = {}
@staticmethod
def createAllTiles() -> list[Tile]:
tiles: list[Tile] = []
tiles.append(TileFactory.createBlank())
tiles.append(TileFactory.createUp())
tiles.append(TileFactory.createRight())
tiles.append(TileFactory.createDown())
tiles.append(TileFactory.createLeft())
return tiles
@staticmethod
def createRandTile() -> Tile:
return TileFactory.createById(randint(0, TileFactory.MAX_ID))
@staticmethod
def createById(id: int) -> Tile:
if (id == TileFactory.BLANK_ID):
return TileFactory.createBlank()
if (id == TileFactory.UP_ID):
return TileFactory.createUp()
if (id == TileFactory.RIGHT_ID):
return TileFactory.createRight()
if (id == TileFactory.DOWN_ID):
return TileFactory.createDown()
if (id == TileFactory.LEFT_ID):
return TileFactory.createLeft()
else:
raise ValueError()
@staticmethod
def createBlank() -> Tile:
return TileFactory._createdTiles.get(TileFactory.BLANK_ID, Tile('./tiles/blank.png'))
@staticmethod
def createUp() -> Tile:
return TileFactory._createdTiles.get(TileFactory.UP_ID, Tile('./tiles/up.png'))
@staticmethod
def createRight() -> Tile:
return TileFactory._createdTiles.get(TileFactory.RIGHT_ID, Tile('./tiles/right.png'))
@staticmethod
def createDown() -> Tile:
return TileFactory._createdTiles.get(TileFactory.DOWN_ID, Tile('./tiles/down.png'))
@staticmethod
def createLeft() -> Tile:
return TileFactory._createdTiles.get(TileFactory.LEFT_ID, Tile('./tiles/left.png'))
Tile 类:
class Tile:
def __init__(self, imgPath: str) -> None:
self.img: pygame.Surface = pygame.image.load(imgPath)
self.imgPath = imgPath
def __eq__(self, value: object) -> bool:
if (type(value) != Tile):
return False
return self.img == value.img
def __hash__(self) -> int:
return self.imgPath.__hash__()
def __str__(self) -> str:
return str(self.__hash__())
def __repr__(self) -> str:
return self.__str__()
和 TileRuleSet 类:
class TileRuleSet:
def __init__(self, up: set[Tile] = set(),
right: set[Tile] = set(), down: set[Tile] = set(), left: set[Tile] = set()) -> None:
self.up: set[Tile] = up
self.right: set[Tile] = right
self.down: set[Tile] = down
self.left: set[Tile] = left
def __str__(self) -> str:
return f"UP: {setToString(self.up)}, RIGHT: {setToString(self.right)}, "\
f"DOWN: {setToString(self.down)}, LEFT: {setToString(self.left)}\n"
def __repr__(self) -> str:
return self.__str__()
但是,当我调用静态 createAll 方法时,控制台中会打印以下内容:
{238499618696605147: UP: {4114546419569344162, 238499618696605147}, RIGHT: {-6386996300615071302, 238499618696605147}, DOWN: {238499618696605147, 6516502529729026507}, LEFT: {-848466221319434871, 238499618696605147}
}
Traceback (most recent call last):
File "[PATH]\tile.py", line 221, in <module>
TileRuleSetFactory.createAll()
File "[PATH]\tile.py", line 136, in createAll
print(ruleSets[TileFactory.createBlank()])
~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: 238499618696605147
如您所见,字典中存在哈希值 238499618696605147,但我仍然收到 KeyError。为什么会发生这种情况,我该如何解决?
尝试使用 dict 的 .get() 方法,在这种情况下,如果从 TileFactory.createBlank() 返回的键在 RuleSets 中不存在,它将返回 false,现在,如果您不这样做,则可以验证该行为没有钥匙。
例如:
if rule_set_value := ruleSets.get(TileFactory.createBlank()):
print(rule_set_value)
else:
#do something
如果是一个集合,请尝试验证其用途:
if TileFactory.createBlank() in ruleSets:
print(ruleSets[TileFactory.createBlank()])