Dark theme

Exceptions and Functional Programming
[outline]


In this part we'll look at two important elements of the core language we've left until now as they are relatively advanced topics: Exceptions and Functional Programming.


First, let's look at what can go wrong with a running program, and how we deal with issues.

Exceptions (powerpoint)

Further info:

The following code will raise an exception of type ExceptionClass:
raise ExceptionClass
This will generate a new object of that type, calling the zero-argument constructor. However, this is the tip of a fairly extensive iceberg of things you can do when generating your own exceptions at different stages of the code execution. for more details on complexities, such as exception chaining and attaching stacktraces, see the documentation on the raise operation.

For more on exiting the system, see the documentation. There's also a library errno for using system error codes.


Quiz: In the Python shell session below, the exception raised was _____________________

>>> int_num = int(input()); print(a)
"2"
*****Exception raised*****

  1. TypeError (info).
  2. ValueError (info).
  3. SyntaxError (info).

Correct! This is tricker than it looks – at first look you might think this is a TypeError, as we're passing in a string where you might think we should be passing in an int. However, input always returns a string, so that can't be the issue, indeed, it's why we use int() to cast to an int. The issue is that the user has typed a string including quote marks. It is therefore the right type, but an inappropriate value, essentially ""2"". It is therefore a ValueError. Funnily enough, because we're expecting a string, you'd get the same error if the user typed two. Note, while we're at it, how we use the rarely seen semicolon delimiter to put two statements on a single line, and avoid having to wait for the user before lining up the print statement.


Another major part of the core language we haven't dealt with is the functional coding parts of the language, which we mentioned at the start of the course. This was better left until we'd covered functions and objects, so we can look at this now. We can divide the functional aspects of Python into those treating functions as objects, and then those specifically that treat such objects as the arguments passed to another function.


Functions as objects (powerpoint)

Further info:

You can find a good introduction to the functional elements of Python in the Python howto documentation.

 


Quiz: In the following code prints ________________________________________

class A():
    def prt(self):
        print("hi")

def prrrt():
    print("changed")

a = A()
a.prt = prrrt
b = A()
b.prt()

  1. nothing, it fails.
  2. changed
  3. hi

Correct! If you look carefully, you'll see we've changed the prt method associated with the object a, not the class A. Changing the latter is slightly more difficult. At the moment we've switched prt with an external function, and this, being external, isn't passed self. If we switch the prt in the class, it will work when called from the class:
class A():
    def prt(self):
        print("hi")

def prrrt():
    print("changed")

A.prt = prrrt
A.prt() # Prints "changed".

However, it gets embedded within the class definition and therefore, when called from an object, is passed self. This means we need to set up prrrt to accept a variable. Here we give it a default so we don't have to supply anything if we don't want to when calling it directly:
class A():
    def prt(self):
        print("hi")

def prrrt(dummy_variable=None):
    print("changed")

A.prt = prrrt
b = A()
b.prt() # Prints "changed".


What this ability to see functions as labelled objects means is that we can pass functions into other functions as arguments. This allows us to generate and use functions that operate on other functions, or run them in special ways. This is a major element of functional programming, moving from the nesting of functions inside function calls (which just transfers the returned data to the next function) to functions that actually need to work on other functions as functions.


Functions as arguments (powerpoint)

Further info:

If you're wondering why lambda functions are called lambda functions, their origins lie in Lambda calculus.

Beware adding lambdas to sequences as they get added as functions, not the result of functions (info).

Find out more about the various iterators that apply functions to sequences in the itertool library.

For more dectorators, see the Python Decorator Library.

If you want to build generator functions that are parameterized, see PEP 342.