1

I am using python 2.6

class Father(object):
    def __init__(self, *args, **kwargs):
        self.is_rich = 'yes'
        self.single  = 'yes'

class Son(Father):
    def __init__(self, *args, **kwargs):
        self.has_job = 'yes'

son = Son()
print dir(son)  --> Does not display Father class attributes is_rich & single? 

Why?

NullException
  • 4,232
  • 8
  • 24
  • 44

3 Answers3

3

You didn't call Father.__init__. You need to do so explicitly or use super1,2:

class Son(Father):
    def __init__(self, *args, **kwargs):
        Father.__init__(self, *args, **kwargs)
        self.has_job = 'yes'

1super considered Super!
2super considered harmful

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • I think it's sort of funny that to create the instance the parameters are in somewhat-reverse order (eg. `son = Son("employed","wealthy","bachelor"`) when using `*args`, `**kwargs`: `class Son(Father): def __init__(self, has_job, *args, **kwargs)`. Compared to creating the instance by repeating the keywords in the child's init: `class Son(Father): def __init__(self, is_rich, is_single, has_job)`. (eg. (`son = Son("wealthy","bachelor","employed"`). – xtian Apr 16 '17 at 00:27
2

You need to call base class's __init__, as python only invokes the first __init__ method found in the class hierarchy the __init__ in Father is never invoked. You can do that using super or using Father.__init__ as shown in @mgilson's answer.

class Son(Father):
    def __init__(self, *args, **kwargs):
        super(Son, self).__init__(*args, **kwargs)
        self.has_job = 'yes'

Demo:

>>> s = Son()
>>> s.is_rich
'yes'
>>> s.single
'yes'
>>> s.has_job
'yes'
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
2

Looks like you didn't have your child chain the initialization up towards its parent.

Perhaps reading this will help: Why aren't Python's superclass __init__ methods automatically invoked?

Community
  • 1
  • 1
Jim Dennis
  • 17,054
  • 13
  • 68
  • 116
  • For what it's worth, by the way, I'd recommend that you normally start your __init__ suite by calling each of your parent constructors, left to right (same order as you'd be reading them, given that the language uses English reserved and keywords. If you have need to perform initialization in some other order, or to skip initialization of any parent classes then you should DEFINITELY document your justification for that. – Jim Dennis Dec 07 '13 at 05:19