I would choose the fourth option, preferring collections.namedtuple :
Animal = namedtuple('Animal', 'number_of_legs favourite_food')
Then you create instances such as:
DOG = Animal(4, ['Socks', 'Meat']) CAT = Animal(4, ['Lasagna', 'Fish'])
and access the values from outside like:
from animals import CAT print CAT.number_of_legs
Actually, it makes no sense to have classes if you don’t need to create any methods, and I think the access form above is more accurate than, for example:
from animals import animals print animals['CAT']['number_of_legs']
namedtuple s, such as vanilla tuple s, are also immutable, so you cannot accidentally reassign, for example. CAT.number_of_legs = 2 somewhere.
Finally, namedtuple is a lightweight data structure that can be important if you create many animals:
>>> import sys >>> sys.getsizeof({'number_of_legs': 4, 'favourite_food': ['Lasagna', 'Fish']}) 140 >>> from collections import namedtuple >>> Animal = namedtuple('Animal', 'number_of_legs favourite_food') >>> sys.getsizeof(Animal(4, ['Lasagna', 'Fish'])) 36