boB Stepp wrote:

> On Wed, Feb 22, 2017 at 10:25 PM, boB Stepp <robertvst...@gmail.com>
> wrote:
>> I am trying to wrap my head around the mechanics of inheritance in
>> Python 3.  I thought that all attributes of a superclass were
>> accessible to an instance of a subclass.  But when I try the
>> following:
>>
>> py3: class A:
>> ...     def __init__(self):
>> ...             self.aa = 'class A'
>> ...
>> py3: class B(A):
>> ...     def __init__(self):
>> ...             self.bb = 'class B'
>> ...
>> py3: a = A()
>> py3: b = B()
>> py3: b.aa
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>> AttributeError: 'B' object has no attribute 'aa'
>>
>> I am unsuccessful...
> 
> I have partially answered my own question, but I am not sure I
> understand the mechanics yet.  Apparently I must explicitly assign
> class A's attribute, aa, to an instance of class B as follows:
> 
> py3: class B(A):
> ...     def __init__(self):
> ...             self.aa = super().aa
> ...             self.bb = 'class B'
> ...
> py3: b = B()
> py3: b.aa
> 'class A'
> 
> I was expecting that all of A's methods and attributes would
> seamlessly be available to any instance of class B, but apparently
> this is wrong-headed on my part.  Instead, it looks like I need to
> explicitly attach A's methods and attributes to B's instances via B's
> self.
> 
> I will continue to mull this over.
 
You are making this harder than need be. If you have one class

class A:
   def __init__(self):
       # complex calculation --> a
       self.a = a
       self.b = "whatever"

you could split the code into two methods, to keep it manageable, say:

class A:
    def __init__(self):
        self.init_a()
        self.b = "whatever"

    def init_a(self):
        # complex calculation
        self.a = a

This will obviously continue to work with two classes:

class A:
    def init_a(self):
        # complex calculation
        self.a = a

class B(A):
    def __init__(self):
        self.init_a()
        self.b = "whatever"

Now what if init_a() is actually called __init__? Just renaming will not 
work

class A:
    def __init__(self):
        # complex ...
        self.a = a

class B(A)
    def __init__(self):
        self.__init__() # this will invoke B.__init__ again
                        # --> infinite recursion
        self.b = "whatever"

so you either have to be explicit

class B(A)
    def __init__(self):
        A.__init__(self) # this will invoke A.__init__
                         # because we told it to
        self.b = "whatever"

or use "black magic"

class B(A):
    def __init__(self):
        super().__init__() # have Python figure out
                           # what to call
        self.b = "whatever"

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to