Are there good reasons to/not to store a list of objects as "sub attributes"? In the example below, I store several animal objects in a Zoo under the animals attribute, e.g. zoo.animals.<animal object referenced by name>. This syntax makes it easier to access the attributes of the stored animals and I'm wondering if there are downsides of this construction I haven't yet considered:
class Animal(object):
def __init__(self, name, num_legs, furry):
self.name = name
self.num_legs = num_legs
self.furry = furry
class ObjAsAttributes(object):
def __init__(self, **kwargs):
for k,v in kwargs.items():
setattr(self, k, v)
class Zoo(object):
def __init__(self, animals):
self.name = 'my zoo'
self.hours = '8am-6pm'
animals = {animal.name:animal for animal in animals}
self.animals = ObjAsAttributes(**animals)
animal_list = [Animal(name='bird', num_legs=2, furry=False),
Animal(name='giraffe', num_legs=4, furry=True),
Animal(name='octopus', num_legs=8, furry=False)]
zoo = Zoo(animal_list)
zoo.animals.bird.num_legs
# returns 2
In my opinion, doing so will make your code hard to debug, inflexible and unreadable. This is a bad idea. What happens if, for example:
for name in vars(obj):
print(getattr(obj, name))
Attributes are meant to "hold data" or "describe features" of a modeled object. You should use them only for that purpose.
As you are mainly looking for fast and easy access, use a dict or OrderedDict:
class Animal(object):
def __init__(self, name, num_legs, furry):
self.name = name
self.num_legs = num_legs
self.furry = furry
class Zoo(object):
def __init__(self, animals):
self.name = 'my zoo'
self.hours = '8am-6pm'
self.animals = {animal.name:animal for animal in animals}
animal_list = [Animal(name='bird', num_legs=2, furry=False),
Animal(name='giraffe', num_legs=4, furry=True),
Animal(name='octopus', num_legs=8, furry=False)]
zoo = Zoo(animal_list)
zoo.animals['bird'].num_legs
# returns 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With