是否可以从作为属性的字典中弹出项目?

时间:2019-07-01 22:33:55

标签: python oop dictionary properties pop

我有一个小问题。我需要从字典中弹出项目,但是字典是类的属性。

    @property
    def hand_scores(self):
        return {'Ones': YatzyHand.score_ones(self.hand), 'Twos': YatzyHand.score_twos(self.hand),
                'Threes': YatzyHand.score_threes(self.hand), 'Fours': YatzyHand.score_fours(self.hand),
                'Fives': YatzyHand.score_fives(self.hand), 'Sixes': YatzyHand.score_sixes(self.hand),
                'One Pair': YatzyHand.score_one_pair(self.hand),
                'Two pairs': YatzyHand.score_two_pairs(self.hand),
                'Three of a kind': YatzyHand.score_three_of_a_kind(self.hand),
                'Four of a kind': YatzyHand.score_four_of_a_kind(self.hand),
                'Yatzy': YatzyHand.score_yatzy(self.hand),
                'Low straight': YatzyHand.score_low_straight(self.hand),
                'High straight': YatzyHand.score_high_straight(self.hand),
                'Full house': YatzyHand.score_full_house(self.hand),
                'Chance': YatzyHand.score_chance(self.hand)}

例如,我希望能够以这种方式弹出项目:

Player.pop('Chance')

我不知道该怎么办。

1 个答案:

答案 0 :(得分:0)

您可以制作字典的本地副本并对其进行修改,但不能修改函数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可用于从实例中删除密钥,并返回其最后一个值。

就我个人而言,我认为拥有这样的lambda字典是一种很差的风格,但是确实有用。

在我看来,一种稍微简洁的技术(也可以让您放回键)是将一组键保留在一个实例变量中,并将它们映射到函数的字典可以保留在函数中。

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)