Sorry folks - my code didn't work due to my debug var count to ensure that I was looping properly.
It should be: media = [] def loadFile(): filename = input('Filename? ') f = open(filename, 'r') createObjects(f) def createObjects(f): '''Takes a file object and iterates through entries, passing them to create object, depending on what object it is.''' for line in f: data = json.loads(line) print(type(data['tpe'])) name = data['name'] platform = data['platform'] dateAdded = data['dateAdded'] tpe = data['tpe'] if data['tpe'] == 'Game': a = createGame(name, platform, dateAdded,tpe) game = {a: tpe} media.append(game) if data['tpe'] == 'Film': a = createFilm(name, platform, dateAdded,tpe) film = {a: tpe} media.append(film) # For some reason I'm only getting one object at a time now when appending to media print(len(media)) def createGame(name, platform, dateAdded, tpe): return Game(name, platform, dateAdded) def createFilm(name, platform, dateAdded, tpe): return Film(name, platform, dateAdded) Also, there is a bug that places an instance variable of dateAdded to tpe, which is causing an error. This might be why I'm not getting more objects than I expect. My class is: import datetime class Media: def __init__(self, name, platform, tpe): self.name = name self.platform = platform date = datetime.datetime.now() datestring = date.strftime("%Y:%m:%d:%H:%M:%s") self.dateAdded = datestring self.tpe = tpe #self.dateAdded = datetime.datetime.now() and from . import media #import media class Game(media.Media): #tpe = 'game' # def __init__(self): # self.type = 'game' Thanks. Adam On Tue, 26 Feb 2019 at 10:02, Cameron Simpson <c...@cskk.id.au> wrote: > Thank you for a well formed problem description. > > However, as Steven has remarked the code you've included doesn't run. > Can you follow up/reply with your actual working script, and also > include some of the output you get. > > That said, I've a few small remarks about the code you have posted: > > On 26Feb2019 09:09, AdamC <kab...@gmail.com> wrote: > >I'm creating lots of objects from json in a file. Part of reading the json > >back means that it iterates over the file and loads a json object and then > >creates the object from the dictionary. > > > >This is my file: > > > >{"name": "Dwarf Fortress", "platform": "steam", "dateAdded": > >"2019:02:25:16:56:1551113768", "tpe": "2019:02:21:13:49:1550756942"} > >{"name": "Jaws", "platform": "Netflix", "dateAdded": > >"2019:02:25:16:56:1551113768", "tpe": "2019:02:21:13:49:1550756960"} > >{"name": "Wargames", "platform": "CLI", "dateAdded": > >"2019:02:25:16:59:1551113984", "tpe": "Game"} > > BTW, I notice that only one of these rows has the "tpe" field set to > "Game" or "Film", specificly the last one. So based on your code below, > only one of these rows gets appended to the media array. Remarks below > on writing code which is less prone to hiding this kind of problem. > > >and these are the functions that help load that file: > > > >media = [] > > > >def loadFile(): > > filename = input('Filename? ') > > f = open(filename, 'r') > > createObjects(f) > > This f=open code would normally be written like this: > > with open(filename, 'r') as f: > createObjects(f) > > That construction ensures that the file gets closed after running > "createObjects()". As it is in your code the file is not explicitly > closed; the CPython interpreter will, as it happens, close the file > pretty promptly when "f" goes out of scope, but the language definition > doesn't require such immediacy. > > >def createObjects(f): > > '''Takes a file object and iterates through entries, passing them to > >create > > object, depending on what object it is.''' > > for line in f: > > count = count + 1 > > data = json.loads(line) > > print(type(data['tpe'])) > > name = data['name'] > > platform = data['platform'] > > dateAdded = data['dateAdded'] > > tpe = data['tpe'] > > if data['tpe'] == 'Game': > > a = createGame(name, platform, dateAdded,tpe) > > game = {a: tpe} > > media.append(game) > > if data['tpe'] == 'Film': > > a = createFilm(name, platform, dateAdded,tpe) > > film = {a: tpe} > > media.append(film) > > These if statements don't cover the case when "tpe" isn't "Game" or > "Film", and (in other circumstances) could conceivably add two objects. > If you construct it like this instead: > > if data['tpe'] == 'Game': > a = createGame(name, platform, dateAdded,tpe) > game = {a: tpe} > media.append(game) > elif data['tpe'] == 'Film': > a = createFilm(name, platform, dateAdded,tpe) > film = {a: tpe} > media.append(film) > else: > print("Unhandled tpe value:", repr(tpe)) > > then (a) only 1 branch can ever apply and (b) reports any unexpected > values which would otherwise _silently_ get ignored. By always having a > final "else" in an if/elif/..../else chain you can catch/observe these > unhandled situations. > > >def createGame(name, platform, dateAdded, tpe): > > return Game(name, platform, dateAdded) > > > >def createFilm(name, platform, dateAdded, tpe): > > return Film(name, platform, dateAdded) > > Unless there's more stuff happening in these functions which you've > stripped out for clarity you could just call the object constructors > directly from the if statements: > > if data['tpe'] == 'Game': > a = Game(name, platform, dateAdded) > game = {a: tpe} > media.append(game) > > >Why would I only get one object in media, even though all three are > >created? > > As you may gather, all three input lines are processed, but only one > gets turned into an object to add to media. Change the if/if into an > if/elif/else and see if things become more obvious. > > Cheers, > Cameron Simpson <c...@cskk.id.au> > _______________________________________________ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > -- -- You back your data up on the same planet? http://www.monkeez.org PGP key: 0x7111B833 _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor