Classes

As you probably know, Python is an object-oriented language, and so has very strong support for objects. In fact, everything in Python is an object. We will mostly use an imperative or functional rather than object-oriented programming style in this course.

Here is the bare minimum about Python objects.

Defining a new class

We define a class A with 2 ‘special’ double underscore methods and one normal method. This class will have an attribute x that is specified at the time of creating new instances of the class.

  • The init method initializes properties of any new instance of A
  • The repr method provides an accurate string representation of A. For example, if we print an instance of A, the repr method will be used. If you don’t specify a repr (or str) special method, the default name when printing only gives the address in memory.

There are many more special method, as described in the official documentation. We will not go there.

In [62]:
class A:
    """Base class."""

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

    def __repr__(self):
        return '%s(%a)' % (self.__class__.__name__, self.x)

    def report(self):
        """Report type of contained value."""

        return 'My value is of type %s' % type(self.x)

Docstrings

In [72]:
A.__doc__
Out[72]:
'Base class.'
In [74]:
help(A)
Help on class A in module __main__:

class A(builtins.object)
 |  Base class.
 |
 |  Methods defined here:
 |
 |  __init__(self, x)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |
 |  __repr__(self)
 |      Return repr(self).
 |
 |  report(self)
 |      Report type of contained value.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)

In [73]:
A.report.__doc__
Out[73]:
'Report type of contained value.'

Making instance of a class

Example of a class without repr.

In [64]:
class X:
    """Empty class."""
In [65]:
x = X()
print(x)
<__main__.X object at 0x1115eda20>

Make new instances of the class A

In [59]:
a0 = A('a')
In [67]:
print(a0)
A('a')
In [60]:
a1 = A(x = 3.14)
In [68]:
print(a1)
A(3.14)

Attribute access

In [51]:
a0.x, a1.x
Out[51]:
('a', 3.14)

Method access

In [52]:
a0.report(), a1.report()
Out[52]:
("My value is of type <class 'str'>", "My value is of type <class 'float'>")

Class inheritance

In [63]:
class B(A):
    """Derived class inherits from A."""

    def report(self):
        """Overwrite report() method of A."""
        return self.x
In [71]:
B.__doc__
Out[71]:
'Derived class inherits from A.'

Make new instances of class B

In [54]:
b0 = B(3 + 4j)
In [55]:
b1 = B(x = a1)

Attribute access

In [56]:
b0.x
Out[56]:
(3+4j)
In [57]:
b1.x
Out[57]:
A(3.14)

Nested attribute access

In [58]:
b1.x.report()
Out[58]:
"My value is of type <class 'float'>"