Вы можете сделать локальную копию словаря и изменить ее, но вы не можете изменить значение в функции hand_scores
, потому что оно создается каждый раз, когда осуществляется доступ к свойству (потому что функция вызывается каждый раз).Если вы хотите изменить его, сделайте вместо него обычную переменную экземпляра.
Затем, чтобы убедиться, что переменные обновлены, вы заставляете исходный словарь содержать функции, которые генерируют значения.
class Player:
def __init__(self):
self._hand_scores = {
'Ones': lambda: YatzyHand.score_ones(self.hand),
'Twos': lambda: YatzyHand.score_twos(self.hand),
...
}
@property
def hand_scores(self):
"Generate the dictionary of hand scores"
return {key: valuefn() for key, valuefn in self._hand_scores.items()}
def pop_hand_score(self, key):
"Remove a score from hand_scores, returning its current value"
return self._hand_scores.pop(key)()
Таким образом, значения в словаре генерируются при каждом вызове, но ключи хранятся в переменной экземпляра.Затем pop_hand_score
можно использовать, чтобы удалить ключ из экземпляра и вернуть его последнее значение.
Лично я думаю, что подобный словарь лямбда-выражений довольно плохой стиль, но он работает.
Немного более чистый метод (на мой взгляд), который также позволил бы вам вернуть ключи обратно, состоял бы в том, чтобы просто сохранить набор ключей в переменной экземпляра, и словарь, отображающий их на функции, мог бы остаться в функции.
class Player:
def __init__(self):
self._hand_score_keys = {'Ones', 'Twos', ...}
def hand_scores(self):
# You could also make this a dict of actual values if you
# don't mind calculating them even when you don't need them.
score_functions = {
'Ones': lambda: YatzyHand.score_ones(self.hand),
'Twos': lambda: YatzyHand.score_twos(self.hand),
...
}
return {key: score_functions[key]() for key in self._hand_score_keys}
def ignore_score(self, key):
self._hand_score_keys.remove(key)
def recall_hand_score(self, key): # needs a better name
self._hand_score_keys.add(key)