Title: SOFTENG 710
1SOFTENG 710
- Python
- Error handling
- Functional programming
- Object-oriented programming
- Modules and packages
-
- Based on Python Essential Reference, Second
Edition, by David M. Beazley
2Error handling exceptions
try do something except IOError, e
Handle I/O error. except TypeError, e
Handle type error. except NameError, e
Handle name error.
Multiple exception-handling blocks are specified
using multiple except clauses.
try do something except IOError pass
To stop an exception propagating, but to take no
other action use the pass statement.
3Error handling exceptions
A single handler can catch multiple exceptions.
try do something except( IOError, TypeError,
NameError ), e Handle I/O, Type or Name
errors.
try do something except print An error
occurred
To catch all exceptions, omit the exception name
and value.
4Error handling exceptions
5Error handling exceptions
try do something except LookupError
Handle both IndexError and KeyError.
try do something except StandardError
Catch any built-in exception.
try do something except Exception
Catch any built-in or use-defined exception.
6Error handling exceptions
To define your own exception class, inherit from
Exception.
import exceptions class NetworkError(exceptions.E
xception) def __init__( self, argsNone)
self.args args
raise NetworkError, cant find host
Actually calls NetworkError( cant find host
) prints NetworkError cant find host
For a user-defined exception to be properly
printed in a traceback, you must store the
message in a variable named self.args at
construction time.
7Error handling assertions
- The assert statement is useful to add debugging
code into a program - The assert statement is followed by a boolean
expression and an optional message - If the boolean expression evaluates false, the
interpreter raises an AssertionError exception
def write_data( file, data ) assert not file
None, write_data file is None
8Functional programming
- A little more on functions
- Parameters are passed by reference
- Where a reference to a mutable object is passed
to a function, any changes made to the object by
the function are reflected in the caller
a 1, 2, 3, 4, 5 def foo( x ) x 3
-55 Modify an element of a. foo( a ) print
a Produces 1, 2, 3, -55, 5
9Functional programming
- Scoping rules
- Each time a function executes, a new local
namespace is created - The namespace contains the names of the
functions parameters and local variables - To resolve a name, the interpreter
- First looks in the local name space
- If there is no match in the local name space, the
global name space is searched - The functions global name space is the module in
which the function was defined - With no match in the global name space, the
interpreter makes a final check in the built-in
name space - If this fails, a NameError is raised
10Functional programming
- The lambda operator
- This creates an anonymous function in the form of
an expression
Expression that must yield a result cant
contain multiple statements
Function parameters
a lambda x, y x y print a( 2, 3 )
Produces 5.
11Functional programming
- map( )
- Takes two arguments
- A function, f, that takes only one argument
- A list, l
- map( ) applies f to each element in l and returns
a new list as the result
a 1, 2, 3, 4, 5, 6 def foo( x )
return 3 x b map( foo, a ) b 3, 6, 9,
12, 15, 18
12Functional programming
- reduce( )
- Takes two arguments
- A function, f, which takes 2 arguments
- A sequence, s
- reduce( ) iterates over s and returns a single
value - f is applied initially to the first two elements
of s the resulting value is then combined with
the third value of s and so on
a 1, 2, 3, 4 def sum( x, y ) return x
y b reduce( sum, a ) b ( ( ( 1 2 ) 3
) 4 ) 10
13Functional programming
- filter( )
- Takes 2 arguments
- A function f that takes 1 argument and returns
true or false - A sequence s
- filter( ) iterates over a list and returns a new
list containing members of s for which f holds
true
a -11, 2, 3, 4 def positive( x )
return x gt 0 b filter( positive, a ) b
2, 3, 4
14Functional programming
- List comprehension
- A powerful way of constructing lists
expression for item1 in sequence1 for
item2 in sequence2 for itemN in
sequenceN if condition
a -3, 5, 2, -10, 7, 8 b abc c 2 s
for s in a c -6, 10, 4, -20, 14, 16 d
s for s in a if s gt 0 d 5, 2, 7, 8
e ( x, y ) for x in a e ( 5, a ),
( 5, b ), ( 5, c ), for y in b (
2, a ), ( 2, b ), ( 2, c ), if x gt
0 ( 7, a ), ( 7, b ), ( 7, c ), (
8, a ), ( 8, b ), ( 8, c )
15Object-oriented programming
class Account A simple class
account_type Basic def __init__(
self, name, balance ) Initialise a new
Account instance self.name name
self.balance balance def deposit( self,
amt ) Add to the balance
self.balance self.balance amt def
withdraw( self, amt ) Subtract from the
balance self.balance self.balance
amt def inquiry( self ) Return the
current balance return self.balance
- Classes
- The class statement
- Defines a set of attributes - which include
methods and class variables - When a class is imported, it is executed this
creates a class object which serves as a name
space
16Object-oriented programming
- The class object for Account defines a name space
with the following members - Name space ? scope
- Within a class name space, references to other
class attributes must be fully qualified
Account.account_type Account.__init__ Account.depo
sit Account.withdraw Account.inquiry
Class attributes can be discovered using
Accounts dictionary Account.__dict__
class Foo def bar( self ) print
bar! def spam( self ) bar( self
) Raises a NameError Foo.bar( self )
This works
17Object-oriented programming
- An instance of a class is created by calling a
class - A class instance is actually implemented as a
dictionary - The dictionary contains the information that is
unique to the instance (i.e. the values of
instance variables) - Within a class, values of instance variables can
be accessed and modified by preceding them with
self - You can add an instance variable at any time!
a Account( Guido, 100 ) Invokes
Account.__init__( a, Guido, 100 ) b Account(
Bill, 10 ) a.deposit( 100 ) Calls
Account.deposit( a, 100 ) b.withdraw( 10 ) name
a.name print a.account_type print a.__dict__
balance 200, name Guido
18Object-oriented programming
- Attribute lookup
- Accessing an attribute works as follows
- First, try the instances dictionary
- If no match, the interpreter tries the class
object used to create the instance - If this fails, base classes are searched
- Finally, and if there is still no match, the
interpreter attempts to invoke the class
__getattr__( ) method - If there is no __getattr__( ) method, an
AttributeError is raised
19Object-oriented programming
- Recall that all instances are reference counted
- When the count reaches zero, the object can be
destroyed - The garbage collector may invoke the special
method __del__( ) on the instance - The del statement simply decrements an objects
reference count - If this causes the objects reference count to
drop to zero, __del__( ), if defined, is called
a Account( Jake, 10 ) b a del a del b
Calls __del__( ) if defined.
a Account( Jake, 10 ) b a a None b 30
No guarantee that the interpreter
will try to invoke __del__( )
20Object-oriented programming
class A varA 42 def method1(self)
print Class A method1 class B varB
37 def method1(self) print Class B
method1 def method2(self) print
Class B method2 class C( A, B ) Inherits
from A and B varC 3.3 def
method3(self) print Class C
method3 class D pass class E( C, D ) pass
- Inheritance
- A class (subclass) can inherit attributes from
others (superclasses) - The subclass may redefine any inherited
attributes - Note an attribute includes variables and methods
21Object-oriented programming
- When searching for an attribute in a base class,
the base classes are searched using a depth-first
algorithm in the same order as specified in the
class definition
c C( ) c.method3( ) Invoke C.method3( c
) c.method1( ) Invoke A.method1( c ) c.varB
Access B.varB
When redefining a method, to call an inherited
definition you need to access it using a fully
qualified name.
class F( A ) def method1( self )
print Class F method1 A.method1( self
)
22Object-oriented programming
- Polymorphism (dynamic binding)
- When accessing a method, i.e. obj.method( ), the
method actually executed is the first match in - The __dict__ attribute of the instance
- The instances class definition
- Base classes
- Information hiding
- All attributes are public!
- Information is achieved through programmer
convention
23Object-oriented programming
- Python is not uniform in its treatment of
built-in types (e.g. lists and dictionaries) and
classes - All classes are of type ClassType
- All class instances are of type InstanceType
- To test for membership in a class, use the
built-in function isinstance
a A( ) b B( ) c C( ) Recall that C is
subclass of A type( a ) type( b )
True! isinstance( a, A ) Returns
1 isinstance( b, A ) Returns 0 B isnt
derived from A isinstance( c, A ) Returns 1
C is derived from A
24Modules and packages
- Recall that any Python source file can be turned
into a module by loading it with the import
statement - Executing import does 3 things
- It creates a new namespace for all objects
defined in the corresponding file - It executes the code contained in the module
- It creates a name within the caller that refers
to the new namespace
25Modules and packages
- Large systems are structured into packages of
modules - A package is defined by creating a directory, of
the same name as the intended package, and
creating a file __init__.py in that directory - When anything is imported from a package, the
packages __init__.py file is executed - __init__.py is often empty but can be used to
initialise package data structures
openrecframework/ __init__.py openrec/
__init__.py lookupService.py
algorithm.py plugins/
__init__.py simplePlugin.py
import openrecframework.openrec.lookupService.look
upException e openrecframework.openrec.lookupSer
vice.lookupException( )
from openrecframework.openrec.lookupService
import lookupException e lookupException( )