In the following Python 3 code, the correct value is written into the daysSchedule
but when iterating to the next value.
class Data:
def getDaysSchedule(scheduleUrl, filterTeam = ''):
with urllib.request.urlopen(scheduleUrl) as request:
data = json.loads(request.read().decode())
daysSchedule = GameList()
for gameData in data["dates"][0]["games"]:
game = Game()
game.gameId = gameData["gamePk"]
game.home.name = gameData["teams"]["home"]["team"]["name"]
game.away.name = gameData["teams"]["away"]["team"]["name"]
print('\n' + str(game.gameId)) # CORRECT VALUE HERE
daysSchedule.games = daysSchedule.games[:] + [game] # HERE HAVE TRIED APPEND BUT THAT DIDN'T WORK EITHER
# DEBUG CODE
menuItems = daysSchedule.games
for testItem in menuItems:
testId = testItem.gameId
title = testItem.home.name + ' VS. ' + testItem.away.name
print(title)
return daysSchedule
I get output from the debug chunk of code above like the following. Each one of this is a write out of one of the rows. And you will see a new row gets added with correct values, but all the previous rows incorrectly get overwritten with this value too.
633855
Chicago Cubs VS. San Diego Padres
Chicago Cubs VS. San Diego Padres
633834
Arizona Diamondbacks VS. New York Mets
Arizona Diamondbacks VS. New York Mets
Arizona Diamondbacks VS. New York Mets
633853
Baltimore Orioles VS. Minnesota Twins
Baltimore Orioles VS. Minnesota Twins
Baltimore Orioles VS. Minnesota Twins
Baltimore Orioles VS. Minnesota Twins
633882
New York Yankees VS. Tampa Bay Rays
New York Yankees VS. Tampa Bay Rays
New York Yankees VS. Tampa Bay Rays
New York Yankees VS. Tampa Bay Rays
New York Yankees VS. Tampa Bay Rays
What in the world is going on -- besides me obviously not having enough caffeine today.
Here is the Games class
class Game(object):
gameId = ''
link = ''
date = ''
time = ''
status = Status()
home = Team()
away = Team()
series = Series()
venue = Venue()
... and the GameList class:
class GameList(object):
games = [Game()]
All the trouble came from the way you use classes. Please, note the difference:
This:
class Game(object):
gameId = ''
link = ''
date = ''
time = ''
status = Status()
home = Team()
away = Team()
series = Series()
venue = Venue()
Vs.
class Game():
def __init__(self):
self.gameId = ''
self.link = ''
self.date = ''
self.time = ''
self.status = Status()
self.home = Team()
self.away = Team()
self.series = Series()
self.venue = Venue()
In the former ones you have class attributes which are attributes common for all instances of this class. While the later ones are instance attributes, which are attributes for a particular instance.
Knowing that, we now see how on each iteration the outer loop adds a new instance of the Game
class to the instance of GameList
, while being different objects (with different id()
, memory locations), they all share thier class attributes, i.e. when the program accessed game.home.name
it was the same for all instances of the Game
class.
It's like a global variable shared among all class instances that was modified on each iteration, despite creation (independent in any other sense) instances of the class.
By the way, we can have both:
class Foo:
class_attr = 'I am shared among all the instances'
def __init__(self):
self.instance_attr = 'I belong only to a particular instance'
In the second case here, the particular instance will be passed as self
implicitly.