Classes Confussion on Concepts - Inheritance and Polymorphism


#1

Hello folks,

this confussion concerns these lessons:
Review of Classes Advanced Concepts

Here is the code:

class SortedList(list):
  
  def append(self, value):
    super().append(value)
    self.sort()

I mean to ask if super() as proxy object represents here the list class or the SortedList class?
First I thought it´s function called on method from parent class, but now it looks to me like it´s a function AND proxy object in one. So virtually two objects as function is object too.

Also the self parameter…is it a representation of method in a way that self = method? The .sort function called in the code is called on self. Does it mean it´s called on method append?

And dont start on some dunder methods. I wouldnt even know how to posit the question.

Can anyone with more understanding pls elaborate?

Thank you.


#2

If we look at the signature line of the SortedList class, it inherits from List so that is what super() acts upon. It is a method, not a list, so has no append() method. We use that in an __init__() method to pass parameters that we do not want to override so they get intialized in the parent class.

self is also not a list but a reference to the current instance, so has no sort()

def append(self, value):
    self.data.append(value)

This assumes that a data variable is already initialized as a list object.


#3

my initial post edited.

** Also the self parameter…is it a representation of method in a way that self = method?**

thats what feels unclear. Do I have always have to reference to current instance in method with self.argument = argument as I usually see in the code? What is the logic behind it? And when it should or not should be used?


#4

Yes to always having self as a parameter of all instance methods. The only place we will see,

self.variable = variable

is in the __init__() method of the class.

def __init__(self, variable):
    self.variable = variable

A class instance is a data wrapper, for starters. It is a closure around that data so all methods can be scoped to that specific data, only, and not the data of other instances. When we invoke a method, the object upon which that method is called becomes self inside that method. self has access to all the instance variables assigned in the __init__() method.

class Foo(object):
  def __init__(self, foo, bar):
    self.foo = foo
    self.bar = bar
  def __repr__(self):
    return "foo: {}\nbar: {}".format(self.foo, self.bar)
foobar = Foo('foo', 'bar')    # instance of Foo
print (foobar)
foo: foo
bar: bar
fazbaz = Foo('faz', 'baz')    # instance of Foo
print (fazbaz)
foo: faz
bar: baz

Both objects are instances of the same class, but their discrete data is preserved.


#5

Hi Roy,

thanks. It think this cleared the waters about the purpose of .self.

Thank you.