Можно ли извлечь элемент из словаря, который является свойством? - PullRequest
0 голосов
/ 02 июля 2019

У меня есть небольшая проблема.Мне нужно извлекать элементы из словаря, но словарь является свойством класса.

    @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 голосов
/ 02 июля 2019

Вы можете сделать локальную копию словаря и изменить ее, но вы не можете изменить значение в функции 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)
...