4

Lets say I've got a class which represents an object that has many properties (simple data types like strings and integers). Should they be represented as instance variables or would the better "pythonic" be to put them into a dictionary?

For example:

class FruitBasket:
    def __init__(self,apples, oranges, bananas, pears): #number of apples, oranges etc...
        self.apples = apples
        self.oranges = oranges
        self.bananas = bananas
        self.pears = pears



class FruitBasket:
    def __init__(self, fruits): #fruits is a dictionary
        self.fruits = fruits
1
  • It depends on how you expect your code to change in the future. The dictionary solution is easier to extend with arbitrary new types of fruits. Commented Aug 6, 2014 at 19:43

4 Answers 4

6

My general philosophy is to use attributes if the set of items is more or less fixed, and use a dictionary if the set may change on an ad-hoc basis. If your FruitBasket is specifically made to contain apples, oranges, bananas and pears, then use attributes. If it may contain any random assortment of other things (e.g., you might sometimes throw in a pineapple or a raspberry), use a dictionary.

One reason can be sort of seem even in your example code. If you use attributes, you have to specify each one literally in the code (e.g., self.pears). Moreover, you often wind up doing what you did here, where you explicitly pass each item as an argument to __init__. This obviously won't work if you later decide to add new fruits. You could keep adding more arguments to __init__, but that quickly becomes unwieldy.

In addition, if you have a fixed set of items, you'll probably be accessing them individually. That is, if you know you only have apples, oranges, bananas, and pears, you can directly access them by name as you did here (self.apples, self.oranges, etc.). If you don't know ahead of time what fruits may be in the basket, you can't know what names to use a prior, so you'll typically process them by iterating over them. It is very easy to iterate over the items of a dictionary. By contrast, iterating over the attributes of an object is fraught with peril, since you can't easily distinguish the attributes that contain data that the object is "about" (e.g., self.pears) from those that pertain to the structure of the object itself (e.g., self.__init__, self.basketColor, self.basketSize, etc.).

In short, if you don't know ahead of time what will be in the basket, you'll want to iterate over its contents, and if you want to iterate over something's contents, it's best to use a type designed for containment (like a list or dict), because these types cleanly separate the container from its contents.

Sign up to request clarification or add additional context in comments.

2 Comments

How about if the values are constant? Lets say my class represents a camera and it needs to get the camera's properties (lens type, mega pixels, company etc). Wouldn't it make more sense to keep them in a dictionary?
@Shookie: It's not a hard-and-fast rule. You could certainly use a dictionary. But if your camera always has exactly those properties, and not others, I think it would make sense to have them as attributes.
0

It depends what are you going to do with it. A dictionary is more flexible, as it easier to expand with new fruits, as you can iterate to get them all. Representing the fruits as members saves you from some typing, but you have to hard-code all the accesses to them.

A middle ground exists, and it is to use the pattern to syncronize both. Here there is some discussion about how to implement it.

And, before you write another class, remember: Stop writing classes.

Comments

0

You probably want to use a dictionary or you can use the new python 3.4 enum! If it should be an enum. https://docs.python.org/3/library/enum.html

from enum import Enum
animal = Enum('Animal', 'ant bee cat dog')
animal.ant

Comments

0

This and very similiar questions have been asked many times before, and there are various AttrDict implementations out there.

However, you should ask yourself if you have any reason at all not to use a dict. If you don't, then the pythonic thing to do is to use a dict, obviously. A class with no methods should probably not be a class at all. You should also consider the fact that not all valid dict keys are valid attribute names.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.