1 Replies - 579 Views - Last Post: 14 January 2017 - 08:07 AM Rate Topic: -----

#1 DK3250  Icon User is offline

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,047
  • Joined: 27-December 13

proper use of super() ?

Posted 14 January 2017 - 03:02 AM

My original program used a base class and a child class like this:
class Base():
    def __init__(self, x):
        self.x = x * 2
        self.childs = []

    def make_child(self):
        self.childs.append(Child(self.x))  # this is just an example, see comment in text below

class Child():
    def __init__(self, x):
        self.child_x = x

value = 10
base = Base(value)  # create an instance of 'Base'
base.make_child()
print(base.childs[0].child_x)

The code works well.
From within the 'Base' class I create new instances of a 'Child' class instance.
Note: This is really two unrelated classes, I just use the names for better understanding below.
In the example only one argument is shown, but I had a long list of arguments: self.x, self.y, self.z,...

In order to simplify the argument list, I did this:
class Base():
    def __init__(self, x):
        self.x = x * 2
        self.childs = []

    def make_child(self):
        self.childs.append(Child())  # creation of child without argument list

class Child(Base):  # Child now inherits from Base
    def __init__(self):
        self.child_x = super().x  # retrieving arguments using the super() function (doesn't work)

value = 10
base = Base(value)
base.make_child()
print(base.childs[0].child_x)

This code does not work, leading to en error message: "AttributeError: 'super' object has no attribute 'x'". This came as an surprise; I expected the super() to point to the Base class - but apparently not.

OK, - time for a work-around. With a slight modification I got it to work:
class Base():
    def __init__(self, x):
        self.x = x * 2
        self.childs = []

    def make_child(self):
        self.childs.append(Child(self))  # creation of child with 'self' as argument

class Child(Base):  # Inheritance no longer needed
    def __init__(self, base):
        self.child_x = base.x  # extraction of attributes from Base class instance

value = 10
base = Base(value)
base.make_child()
print(base.childs[0].child_x)


So, here I have shown two examples of working code and one example of code not working.
The problem is that I really would like to understand why the super() does not produce a pointer to the Base class instance.
Your input is much appreciated.

EDIT: I realize that in my last example I am back to two unrelated classes.

This post has been edited by DK3250: 14 January 2017 - 06:07 AM


Is This A Good Question/Topic? 1
  • +

Replies To: proper use of super() ?

#2 DK3250  Icon User is offline

  • Pythonian
  • member icon

Reputation: 318
  • View blog
  • Posts: 1,047
  • Joined: 27-December 13

Re: proper use of super() ?

Posted 14 January 2017 - 08:07 AM

OK, I've spend some more time on this.
Apparently, super() can only be used with methods, - not with attributes.
This works fine:
class Base():
    def __init__(self, x):
        self.x = x * 2
        self.childs = []

    def make_child(self):
        self.childs.append(Child())

    def prt(self):
        print("Here")

class Child(Base):
    def __init__(self):
        super().prt()

value = 10
base = Base(value)
base.make_child()

Then it is only the error message that I find misleading:
"AttributeError: 'super' object has no attribute 'x'"
Actually 'super' does have an attribute 'x'; it just isn't accessable using the super() function.
These error messages would be more informative:
"MethodError: 'super' object has no method 'x'" or "AttributeError: 'super' cannot access attributes (only methods)"

This post has been edited by DK3250: 14 January 2017 - 08:08 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1