1

Similar question to this, I was wondering what is the right/common way to implement attribute of an attribute in python. Or I am wrong already with such a thought. Here are the examples:

method 1

It's obvious that it doesn't allow self.father.height

class household:
    def __init__(self, address, name0, height0, name1,height1 ):
        self.address = address
        self.father.name = name0
        self.father.height = height0
        self.mother.name = name1
        self.mother.height = height1

household("198 Ave", "John", 6.4, "Jean",5.2)

output:
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-180-09f6784cb40e> in <module>
----> 1 household("198 Ave", "John", 6.4, "Jean",5.2)

<ipython-input-179-9ccb52cdb476> in __init__(self, address, name0, height0, name1, height1)
      2     def __init__(self, address, name0, height0, name1,height1 ):
      3         self.address = address
----> 4         self.father.name = name0
      5         self.father.height = height0
      6         self.mother.name = name1

AttributeError: 'household' object has no attribute 'father'

method 2

It works well by using a dictionary without the attribute of an attribute, but I tend to use method 1 although it does not work for some reason.

class household:
    def __init__(self, address, name0, height0, name1,height1 ):
        self.address = address
        self.father = {"name":name0,"height":height0}
        self.mother = {"name":name1,"height":height1}

household("198 Ave", "John", 6.4, "Jean",5.2)
Albert G Lieu
  • 891
  • 8
  • 16
  • You can read about Classes and Object Oriented programming in python, will help you in this situations: https://docs.python.org/3/tutorial/classes.html – Damião Martins Apr 01 '21 at 23:47
  • maybe, create a parent class and pass those object in a list and save the list in attibute name parent – sahasrara62 Apr 02 '21 at 00:02

4 Answers4

1

It seems that you can get something close to what you intended using namedtuple:

from collections import namedtuple

class household:
    def __init__(self, address, name0, height0, name1, height1 ):
        self.address = address
        Parent = namedtuple('Parent', ['name', 'height'])
        self.father = Parent(name0, height0)
        self.mother = Parent(name1, height1)

Example:

h = household("198 Ave", "John", 6.4, "Jean",5.2)
print(h.father.name, h.father.height)

It gives:

John 6.4
bb1
  • 7,174
  • 2
  • 8
  • 23
1

what you need to do is that you first need to initialise self.father and then use self.father.name.

You should also read more about OOP from the python documentatoion

1

I don't know which method is the typical/common way to implement it. But certainly, we can get method 1 to work. @angadsinghbedi is right, we can initialise self.father as an valid object with type("",(),{}). For more details about creating an empty object, see here

class household:
    def __init__(self, address, name0, height0, name1,height1 ):
        self.address = address
        self.father = type("person", (),{})()
        self.father.name = name0
        self.father.height = height0
        self.mother = type("person", (), {})()
        self.mother.name = name1
        self.mother.height = height1

house0 = household("198 Ave", "John", 6.4, "Jean",5.2)
house0.father.name
# John 
Albert G Lieu
  • 891
  • 8
  • 16
0

Method 1 doesn't work for exactly the reason the error message give you: you cannot create a sub-attribute for an attribute that doesn't exist. You would have to initialize self.father to something with a compatible structure; then your could assign to the child attributes.

Assigning the dict is a very good way to accomplish your desired result.

If I were to implement this, I would take the name/height pairs as a list or tuple of entries for later expansion. Some people have one parent; others have more than two.

household("198 Ave", [("John", 6.4), ("Jean",5.2)] )
Prune
  • 76,765
  • 14
  • 60
  • 81