Dark theme

Control Flow III: Classes and Objects
[outline]


In this part we look at control flow beyond a single file, looking at how to create objects ourselves.


First up, let's look at the basics of objects. Objects are variables like any other, they just contain other variables and functions, rather than specific values. But what type are they? The answer is that we create a new type for the objects we want to build. This is called a "class", and usually sits in a file other than the main program. We'll first look at how we connect files together, and then how we construct classes and turn them into objects.

Object basics (powerpoint)

Further info:

You can find a nice analysis of bound and unbound methods by Hillel Wayne at Stupid Python Tricks.

To see something of the complications of where you can put variables in modules, classes, and methods, follow through these example scripts: main.py; scopetest.py;


Quiz: Download, read, and run the following files: rocketmain.py; rockettest.py. The launched rocket always crashes on the takeoff site. This is because _____________________

  1. current_coordinates is class level and shared by both rockets.
  2. current_coordinates is object level, but restarted each iteration.
  3. self.launched isn't read in the update_location method.

Correct! Although we're using self, because the variable is assigned at the class level, it is a class variable. Remember, if there's no object-level version of a variable, Python defaults to the class level. These means that when we tell the second rocket to update its position as still on the launch pad, the first rocket gets the same coordinates. Uncommenting the line suggested solves this issue by assigning again within the method. As soon as this happens, the variable becomes associated with the object, as assignment within methods is either associated with the method or (in the case of "self" variables) the object. Note that most of the assignments are to mutable contents, not replacing the variable. The uncommented line replaces the whole variable.


Object Oriented Programming holds three philosophical ideas as central: Encapsulation; Polymorphism; and Inheritance. Here we'll look at these ideas and how Python implements them.


Further info:

If you really want to do polymorphism in Python, you can write a single dispatch generic function. You can also create methods with the same name using decorators. See, for example: property.

Although design by contract support isn't especially foregrounded in Python, there are pre-existing ABCs in the collections library and you can also make and check your own ABCs with the ABC library.

Information about the standard object that all classes inherit isn't that great, but there is a list of at least some of the methods in the datamodel documentation.

If you override specific methods, classes can act like new types of numbers, sequences, or mappings. Indeed, you can even override standard operators like "+" by overriding such methods. For more info see the datamodel documentation.

For information on the complications of super, see Python's Super is nifty, but you can't use it and Python's super() considered super!.

 


Quiz: This code, which overrides the standard "+" operator prints ________________________________________

class EvenInt(int):

    def __init__(self, i):
        self.value = i

    def __add__(self, other):
        if (self.value + other) % 2 == 1:
            return (self.value + other + 1)
        else:
            return (self.value + other)

a = EvenInt(3)
b = a + 2
print(b)

  1. 6.
  2. 5.
  3. 7.

Correct! When the "+" symbol is used between any objects or literals, the left hand value's __add__ method is called to find out what to do. Here's we've overridden this to only return even numbers. Neat hu!? The only issue is that if you work out 2 + a you'll find it's still 5 as we call the "2"s __add__ method. This can be fixed by overriding the reverse-add method in EvenInt (download):
    def __radd__(self, other):
        return self.__add__(other)


One of the chief notions of encapsulation is that you shouldn't mess about with variables in classes directly. Python symultaneously tries to keep access to variables simple while solving this issue. Next we'll see how. We'll also look at how you talk about classes and their public elements.


Access Control (powerpoint)

Further info:

Details of the property() builtin function can be found in the documentation.


Once we have classes and objects of our own, we can start to build up applications to do jobs from these reusable components. At that stage, we then need some way of visualizing how classes come together to make an application, and how the code works together; we also need some way of sharing this with other people who may be working with us. The answer to this issue is the Unified Modeling Language (UML).


Further info:

For info on UML, see the useful links page as well as the Wikipedia page.

UML (powerpoint)