[Tutor] making a list of a custom object
Steven D'Aprano
steve at pearwood.info
Sun Sep 21 07:13:02 CEST 2014
Hi Kate, and welcome!
My replies are interleaved between your questions.
On Fri, Sep 19, 2014 at 04:25:50PM -0500, Kate Reeher wrote:
> I have a custom class called Game, and it has a variable called
> "goals". I'd like to make this a list of custom objects, with various
> information about the goals.
Unfortunately, either your email, or my email, mangled your code below.
I've tried to reconstruct it as well I can, but please don't hesitate to
correct me if I got it wrong.
> class Game:
> goals = {}
>
> class Goal(object):
> def __init__(self,time,goal_by,assist_by,team,is_powerplay ):
> self.time=time
> self.goal_by=goal_by
> self.assist_by=assist_by
> self.team=team
> self.is_powerplay=is_powerplay
>
> Is that Goal class set up correctly?
I can't be absolutely sure, because I'm not sure of your intention, but
it looks correct to me. That's certainly the usual way to set up a
class.
> For an instance of Game called game, is this how you'd set a variable
> of a goal?
> game.goals[i].time= time
You could do it that way to modify an existing goal. (By the way, in
Python circles, we prefer to talk about "attributes" of instances, not
instance variables. If you are interested, I'll give you my standard
rant about this later :-)
Your Game class is a little unusual though. It's not *wrong*, just
unusual, perhaps you intended to do it this way. You have set the Game
class to use a single "class attribute", which means that all
instances will share it. (Actually, the rules are a little more complex
than that, but for now thinking of it as a shared attribute isn't far
wrong.) Was that intentional?
If you're familiar with Java, I think that a class attribute is close to
a Java static variable. (I'm not a Java expert, so I may be wrong.)
If you intend to have multiple Game instances, each with their own
independent set of goals, you would write it like this:
class Game:
def __init__(self):
goals = {}
but I'm not sure why the goals are kept in a dict. That would require
you to keep track of whether each goal is the first, second, third...
goal yourself. I think you want an ordered list:
class Game:
def __init__(self):
goals = []
red_vs_blue = Game()
shirts_vs_skins = Game()
# Add new goals.
red_vs_blue.goals.append(Goal(...)) # Fill in the appropriate args.
shirts_vs_skins.goals.append(Goal(...))
red_vs_blue.goals.append(Goal(...))
# Modify existing goals (but why would you do this?)
red_vs_blue.goals[0].team = 'green'
Because each game has its own list of goals, you can run multiple games
at the same time. You don't have to track the index of the latest goal,
you just append a new goal. You only need to care about the index if you
want to modify an existing goal.
On the other hand, what you originally wrote, with a shared class
attribute, isn't *wrong*. If you absolutely know that there will never
be more than one game at a time, there is no need to bother creating a
Game instance:
class Game:
goals = []
Game.goals.append(Goal(...))
Game.goals.append(Goal(...))
Game.goals[0].team = 'green'
In this case, you can think of the Game class as being almost like a
singleton instance. (Not quite the same, but it does the same job.)
As I said, this is fairly unusual in Python though. Normally you would
stick to standard "one class, multiple instances, each with their own
set of attributes" design.
> I'm finding how python does data classes INCREDIBLY confusing, for
> whatever reason, so any help would be appreciated.
Sorry to hear that. Please don't hesitate to ask about anything
confusing. Giving concrete examples is good, and if you are familiar
with some other language, feel free to say so.
--
Steven
More information about the Tutor
mailing list