1

I have created an Game class which has a dictionary attribute of players as an attribute, which should have ~36 players in it.

I am iterating though a loop, creating a new instance of a Game object with each iteration and printing the contents of each player onto a csv file.

However, with each iteration although a new object is created, it seems that the player attribute is being appended to rather than being garbage collected.

sheet = open('playerGames.csv', 'w+')
gameNum = 2018020001

while gameNum < 2018020015:

    game = Game(gameNum)

    print(len(game.players), end=", ")

    for player in game.players:
        for stat in game.players[player]:
            sheet.write(str(game.players[player][stat]) + ",")
        sheet.write("\n")
    game = None

    gameNum = gameNum + 1

The print statement in the above should print a number about 36 each time however it outputs the following 36, 72, 108, 144, 163, 199, 217, 253, 289, 325, 361, 397, 433, 469

Should the garbage collection not clear this up? I have added the game = None statement in hopes that the entire object gets collected, however that does not seem to work.

Cory L
  • 273
  • 1
  • 12
  • What does `Game(gameNum)` does? I mean what does the constructor do, how is the variable `players` assigned? Moreover how is players declared inside the `Game` class? – Dani Mesejo Oct 19 '19 at 13:26
  • @DanielMesejo That is creating the object. The game number is given as a parameter and __inti__() pulls data from an API with this number to create the attributes. Unfortunately I cannot really post the code for the Game class. – Cory L Oct 19 '19 at 13:29
  • @DanielMesejo players is declared at the top of the class as an empty dictionary ```players = dict()``` and then in the constructor the API fills the dictionary with playerID keys and another dictionary of stats for the player as a value for each key. – Cory L Oct 19 '19 at 13:31
  • 1
    Can you share the code that fills the dictionary? My guess is that you are inserting new players each time you do `Game(gameNum)` try doing something like `players = dict()` inside the `__init__`. – Dani Mesejo Oct 19 '19 at 13:36
  • @DanielMesejo That worked! seems like it's treating players as a static variable when it's declared outside the constructor. I don't do OOP in python that often, is there a way to declare non-static attributes outside of your constructor class in python, or is this just not done in python? Also if you want to post your comment as a response I can mark it as a solution. – Cory L Oct 19 '19 at 13:46
  • `game = None` is unnecessary; garbage collection will be triggered for the `Game` instance whether the next value of `name` is `None` or another `Game` instance, and there is likely little reason to worry about a single `Game` instance sitting around in memory. – chepner Oct 19 '19 at 14:00

1 Answers1

2

Given that players is defined as a global variable, you need to reset in your constructor, something like this:

class Game:

    def __init__(self, n):
        players = dict()

Having a global variable is a bad practice in any language, see this. If players is a property of the Game objects you should do instead:

class Game:

    def __init__(self, n):
        self.players = { }  # dictionary construction expression
Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76