I have begun to take my first steps in learning python and am trying to start using classes.
I have this simplified version so far:
class ThingsInTheFridge(object):
def __init__(self):
self.milk = False
self.yogurt = False
self.bread = True
self.umbrella = True
There will be about 30 things in my class and each is assigned True or False (I have shortened the list for this question).
What is the most efficient way to assign them?
I have thought about this but it doesn't seem to improve things especially when the list increases in size:
self.milk, self.yogurt = False, False
EDIT: I perhaps should have mentioned there are other items in the class to (I omitted them because I didn't think it would matter):
class ThingsInTheFridge(object):
def __init__(self):
self.milk = False
self.yogurt = False
self.bread = True
self.umbrella = True
self.bulb = "maker name"
self.shoes = 2
You might actually be better off using a set of strings instead of individual flag members. Something like the following might work better for what you seem to be trying to do.
I think your main focus should be readability and the underlying data structure.
Something like this is very readable and (likely) as high performance as you can achieve by rolling you own:
Now try it:
This is based on the collection module Counter class. You are unlikely to come up with something that is native Python that is faster.
If you really care about runtime efficiency, you're almost certainly looking in the wrong place. If initializing your members takes too long (which is very unlikely… but if you profile and find this is the hotspot…), the right answer is to use
__slots__
, not to change the way you do the initialization.If you care about programmer efficiency (readability, and to a lesser extent writability), you can always do this:
If you want to do things more dynamically, you could do something like this with
setattr
, but I wouldn't recommend it:The reason I wouldn't recommend it is that, if you need to do things dynamically at this level, you also probably need to be dynamic at the access level, which means you really should be using a
dict
orset
, as explained by Lattyware.You could also go overboard and build yourself a prototype-style OO system on top of the class-style system, or create a metaclass that initializes instances based on class information, etc., but, as the start of this sentence indicates, that would be going overboard.
I think this displays a problem with your model of storing the data. You probably want to be using a data structure like a set, not just attributes.
For example:
Then just store the ones you want in the
stored
set. Sets have very fast performance for membership checks, so to check, you can simply do"milk" in stored
, for example.If you really wanted to keep the interface you have, you could use
__getattr__()
to override the action you get upon asking for an attribute:This will return
False
to anything not in the fridge, if you needed it to only respond to possible items, that could be easily done:Naturally, setting can be done too:
An alternative to this would be a dict to
True
/False
- I can't really say I think either is particularly better, one might suit your project more. Just use whatever works best for you.