简体   繁体   中英

How to alter a variable defined in a parent class in the child class without altering the parent class variable itself?

I'm trying to create two subclasses based on the same parent class, so that they each have their own versions of the same variables defined in the parent object. However I realized that changing these variables in one of these subclasses will cause the versions in the other subclass to change as well. I know I am probably not fully understanding the idea of Inheritance. Please help!

import random


class PlayerParent():
    id = 1

    # Cooperate: True; Betrayal: False
    opponent_moves_history = {}
    self_moves_history = {}

    def append_opponent_history(self, round_num, c_true, misunderstand=0.0):

        # randomly change the result based on probability given in misunderstand
        random_num = random.uniform(0, 1)
        if random_num <= misunderstand:
            c_true = not c_true
        self.opponent_moves_history[round_num] = c_true

    def append_self_history(self, round_num, c_true, misunderstand=0.0):
        # randomly change the result based on probability given in misunderstand
        random_num = random.uniform(0, 1)
        if random_num <= misunderstand:
            c_true = not c_true
        self.self_moves_history[round_num] = c_true

    score = int(0)

    def score_keeper(self, round_num):
        if (self.opponent_moves_history[round_num] == True) and (self.self_moves_history[round_num] == False):
            self.score += 7
        if (self.opponent_moves_history[round_num] == True) and (self.self_moves_history[round_num] == True):
            self.score += 5
        if (self.opponent_moves_history[round_num] == False) and (self.self_moves_history[round_num] == True):
            self.score += 1
        if (self.opponent_moves_history[round_num] == False) and (self.self_moves_history[round_num] == False):
            self.score += 2

    def get_score(self):
        return self.score


class TitForTat(PlayerParent):
    def rule(self, round_num):
        if len(self.opponent_moves_history) == 0:
            return True
        else:
            return self.opponent_moves_history[round_num - 1]


class Random(PlayerParent):
    def rule(self, round_num):
        random_num = random.uniform(0, 1)
        if random_num >= 0.5:
            return True
        else:
            return False


Random = Random()
Random.id = 1
TitForTat = TitForTat()
TitForTat.id = 2


def match(a, b):
    game_counter = 1
    # while game_counter <= 10:
        #a_result = a.rule(game_counter)
        # b_result = b.rule(game_counter)
        # print(a_result, b_result)

        # a.append_self_history(game_counter, a_result)
        # b.append_opponent_history(game_counter, a_result)

        # b.append_self_history(game_counter, b_result)
        # a.append_opponent_history(game_counter, b_result)

        # a.score_keeper(game_counter)
        # b.score_keeper(game_counter)

        # game_counter += 1
    # print(a.get_score(), b.get_score())
    a.self_moves_history[1] = True
    print(a.self_moves_history, '\n', b.self_moves_history)


match(Random, TitForTat)

Resulting a.self_moves_history and b.self_moves_history is identical even though no alteration has been done to the b class variable.

I commented out chunks of the codes just to test where went wrong.

You are making opponent_moves_history a class variable, so naturally any change to it is class-wide.

In your case you should make opponent_moves_history , along with self_moves_history and id instance variables instead, so that changes made to them are specific to the instances.

class PlayerParent():
    def __init__(self):
        self.id = 1
        self.opponent_moves_history = {}
        self.self_moves_history = {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM