UNIT3
UNIT3
Unit – III
Errors and Exceptions: Syntax Errors, Exceptions, Handling Exceptions,
Raising Exceptions, User-defined Exceptions, Defining Clean-up Actions,
Redefined Clean-up Actions.
Functions: What are Functions, Defining and Creating functions, Function
Arguments: Formal and Variable length, Calling functions, Recursive Functions
and Variable Scope. Modules: Modules, Standard Modules, Importing Modules,
Namespaces and Packages.
The first statement assigns an input value to the variable length. The next
statement attempts to print the value of the variable lenth. Python responds that
this name is not defined. Although the programmer might have meant to write
the variable length, Python can read only what the programmer actually entered.
This is a good example of the rule that a computer can read only the instructions
it receives, not the instructions we intend to give it.
The next statement attempts to print the value of the correctly spelled
variable. However, Python still generates an error message.
>>> print(length)
SyntaxError: unexpected indent
final example, the programmer attempts to add two numbers, but forgets to
include the second one:
>>> 3 +
SyntaxError: invalid syntax
Exceptions
Any programming language has two types of errors.
1. Syntax error : Errors due to invalid syntax.
Ex: print ‘hai’ # gives syntax error missing parenthesis in call to print
- Syntax errors are fixed by programmer, once fixed program can be
executed normally
What is an Exception?
Exception is a run time error.
An unwanted, unexpected event that disturbs normal flow of the program
is called Exception.
Example: our program requirement is read the data from a remote file
located in Landon. At runtime if Landon file is not available program is
terminated abnormally
exception is that FileNotFoundError.
If the Landon file not available our program should not be terminated
abnormally. We have to provide some local file to continue rest of the program
normally. This is nothing but Exception Handling.
3
Exception handling does not fix the run time error. It provides the
alternative way to continue the execution of rest of the program.
Exception hierarchy
4
Example
Case1:- no exception
1,2,3&5 are executed
Case2:- if exception rised at statement2
1,4,5 are executed.
once it comes out of try block control never goes back. Rest of
the try block never executed so write only risky code inside of the try
block.
Case 3:- if exception rised at statement4
exceptions can be rised in except and finally blocks also sometimes
- causes abnormal termination.
Case4:- if exception rised in try block and if corresponding except block is not
present
- causes abnormal termination.
Note: within the try block if anywhere an exception rised then the rest of try
block won’t be executed even though we handled that exception. Hence within
the try block we have to take only risky code and length of the try block should
be as less as possible.
try:
print(10/0)
except ZeroDivisionError as info:
print(“exception raised due to”, info)
Output:
exception raised due to division by zero
Example:
Test case1:
Test case2:
Test case3:
7
Exception subclasses should come before its super class exceptions why
because except statement which has super class will handle all its sub
classes exceptions .
It never give chance to handle for its sub class
except:
statement
Note: If try with multiple except blocks available then default except
block should be last, otherwise we will get SyntaxError.
finally keyword
finally is a block always associated with try and except to maintain
clean up code.
Example:
Output:
hai
file closed
st1
st2
try:
st3
except:
st4
finally:
st5
except:
st6
finally:
st7
st8
when exception rised in inner try block, inner except block will handle
exception. If inner except block unable to handle, then outer except block
will handle.
Example:
- if elseTryEx.py file available no exception raised in try block then else block
will be executed.
- if exception raised else block will not be executed.
Types of exceptions
• There are two types of exceptions in python
1. Predefined / built in exceptions: when the exception raised in python
program, python virtual machine creates exception object and stops the
program execution and gives the information to the programmer.
Ex: ZeroDivisionError, ValueError, TypeError etc.
2. User defined exceptions / customized exceptions: user or programmer
can raise his own exceptions explicitly to deal with common problems
such as
a) attempting to enter invalid PIN in ATM transactions.-InvalidPinError
b) attempt to enter negative salary for an employee- NegativeSalaryError
c) attempt to enter wrong username and password- WrongDetailsError
d) attempt to withdraw more amount than existing.-
InsufficientFundsError
Raising Exceptions
raise exceptions by user
‘ raise’ statement is used to raise the exceptions forcefully by the user
rather than python virtual machine.
Example
12
User-Defined Exceptions
By inheriting classes from the typical built-in exceptions, Python also lets
us design our customized exceptions.
Here is an illustration of a RuntimeError. In this case, a class that derives
from RuntimeError is produced. Once an exception is detected, we can use this
to display additional detailed information.
13
We raise a user-defined exception in the try block and then handle the
exception in the except block. An example of the class EmptyError is created
using the variable var.
Code
class EmptyError( RuntimeError ):
def __init__(self, argument):
self.arguments = argument
Once the preceding class has been created, the following is how to raise an
exception:
Code
var = " "
try:
raise EmptyError( "The variable is empty" )
except (EmptyError, var):
print( var.arguments )
Output:
2 try:
----> 3 raise EmptyError( "The variable is empty" )
4 except (EmptyError, var):
raise SyntaxError
File "<string>", line None
SyntaxError: <no detail available>
The final clause will execute no matter what, however, the else clause executes
only if an exception was not raised.
Example 2 − Let's try to raise an exception by making a file read-only and try
to write onto it, thus causing it to raise an exception.
file = open('finally.txt', 'r')
try:
file.write("Testing1 2 3.")
print("Writing to file.")
except IOError:
print("Could not write to file.")
else:
17
print("Write successful.")
finally:
file.close()
print("File closed.")
Above program will give an output, something like −
Could not write to file.
File closed.
In case we have an error, but we have not put any except clause to handle it. In
such a case, the clean-up action (finally block) will be executed first and then
the error is raised by the compiler. Let's understand the concept with the below
example −
Example
Output
File closed.
Traceback (most recent call last):
File "C:/Python/Python361/finally_try_except1.py", line 4, in <module>
file.write(4)
TypeError: write() argument must be str, not int
So from above, we can see that, finally, clause executes always, irrespective of
whether an exception occurs or not.
18
The problem with this code is that it leaves the file open for an indeterminate
amount of time after this part of the code has finished executing. This is not an
issue in simple scripts, but can be a problem for larger applications.
The with statement allows objects like files to be used in a way that ensures they
are always cleaned up promptly and correctly.
with open("myfile.txt") as f:
for line in f:
print(line, end="")
After the statement is executed, the file f is always closed, even if a problem was
encountered while processing the lines. Objects which, like files, provide
predefined clean-up actions will indicate this in their documentation.
Assertions in Python
An assertion is a sanity-check that you can turn on or turn off when you
are done with your testing of the program.
The easiest way to think of an assertion is to liken it to a raise-if
statement (or to be more accurate, a raise-if-not statement). An
expression is tested, and if the result comes up false, an exception is
raised.
Assertions are carried out by the assert statement, the newest keyword to
Python, introduced in version 1.5.
Programmers often place assertions at the start of a function to check for
valid input, and after a function call to check for valid output.
Example
Here is a function that converts a given temperature from degrees Kelvin
to degrees Fahrenheit. Since 0° K is as cold as it g ets, the function bails out if it
sees a negative temperature
#!/usr/bin/python3
def KelvinToFahrenheit(Temperature):
assert (Temperature >= 0),"Colder than absolute zero!"
return ((Temperature-273)*1.8)+32
print (KelvinToFahrenheit(273))
print (int(KelvinToFahrenheit(505.78)))
print (KelvinToFahrenheit(-5))
Functions
What are Functions
A function is a block of organized, reusable code that is used to perform a
single, related action. Functions provide better modularity for your application
and a high degree of code reusing.
As you already know, Python gives you many built-in functions like
print(), etc. but you can also create your own functions. These functions are
called user-defined functions.
Example
The following function takes a string as input parameter and prints it on
standard screen.
def printme( str ):
"This prints a passed string into this function" # docstring
print(str)
return
21
Calling Functions
Defining a function only gives it a name, specifies the parameters that are
to be included in the function and structures the blocks of code.
Once the basic structure of a function is finalized, you can execute it by
calling it from another function or directly from the Python prompt. Following
is the example to call printme() function −
Example
def my_function():
print("Hello from a function")
my_function()
Example:
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
print str
return;
Output:
I'm first call to user defined function!
Again second call to the same function
The parameter mylist is local to the function changeme. Changing mylist within
the function does not affect mylist. The function accomplishes nothing and
finally this would produce the following result −
Values inside the function: [1, 2, 3, 4]
Values outside the function: [10, 20, 30]
Function Arguments
Information can be passed into functions as arguments. Arguments are
specified after the function name, inside the parentheses. You can add as many
arguments as you want, just separate them with a comma.
The following example has a function with one argument (fname). When
the function is called, we pass along a first name, which is used inside the
function to print the full name:
Example
def my_function(fname):
print(fname + " Refsnes")
my_function("Emil")
my_function("Tobias")
my_function("Linus")
Output:
Emil
Tobias
Linus
23
Parameters or Arguments?
The terms parameter and argument can be used for the same thing:
information that are passed into a function.
From a function's perspective: A parameter is the variable listed inside the
parentheses in the function definition. An argument is the value that is sent to
the function when it is called.
x=10
y=15
sum(x,y)
Required Arguments
By default, a function must be called with the correct number of
arguments. Meaning that if your function expects 2 arguments, you have to call
the function with 2 arguments, not more, and not less.
Example
This function expects 2 arguments, and gets 2 arguments:
def my_function(fname, lname):
print(fname + " " + lname)
my_function("Emil", "Refsnes")
Example:
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
24
print str
return;
Keyword Arguments
You can also send arguments with the key = value syntax. This way the
order of the arguments does not matter.
Example
def my_function(child3, child2, child1):
print("The youngest child is " + child3)
Default arguments
A default argument is an argument that assumes a default value if a value
is not provided in the function call for that argument. The following example
gives an idea on default arguments, it prints default age if it is not passed −
# Function definition is here
def printinfo( name, age = 35 ):
"This prints a passed info into this function"
print "Name: ", name
print "Age ", age
return;
25
Output:
Name: miki
Age 50
Name: miki
Age 35
Variable-length arguments
You may need to process a function for more arguments than you
specified while defining the function. These arguments are called variable-
length arguments and are not named in the function definition, unlike required
and default arguments.
Syntax for a function with non-keyword variable arguments is this −
def functionname([formal_args,] *var_args_tuple ):
"function_docstring"
function_suite
return [expression]
An asterisk (*) is placed before the variable name that holds the values of
all nonkeyword variable arguments. This tuple remains empty if no additional
arguments are specified during the function call. Following is a simple example
# Function definition is here
def printinfo( arg1, *vartuple ):
"This prints a variable passed arguments"
print "Output is: "
print arg1
for var in vartuple:
print var
return;
Output is:
10
Output is:
70
60
50
If you do not know how many arguments that will be passed into your
function, add a * before the parameter name in the function definition. This way
the function will receive a tuple of arguments, and can access the items
accordingly:
Example
If the number of arguments is unknown, add a * before the parameter
name:
def my_function(*kids):
print("The youngest child is " + kids[2])
Output:
Value of total : 30
Value of total : 40
27
Output:
Inside the function : 30
Outside the function : 30
Recursion
Python also accepts function recursion, which means a defined function
can call itself.
Recursion is a common mathematical and programming concept. It means
that a function calls itself. This has the benefit of meaning that you can loop
through data to reach a result.
The developer should be very careful with recursion as it can be quite
easy to slip into writing a function which never terminates, or one that uses
excess amounts of memory or processor power. However, when written
correctly recursion can be a very efficient and mathematically-elegant approach
to programming.
In this example, tri_recursion() is a function that we have defined to call
itself ("recurse"). We use the k variable as the data, which decrements (-1) every
time we recurse. The recursion ends when the condition is not greater than 0
(i.e. when it is 0).
28
To a new developer it can take some time to work out how exactly this
works, best way to find out is by testing and modifying it.
Example
Recursion Example
def tri_recursion(k):
if(k > 0):
result = k + tri_recursion(k - 1)
print(result)
else:
result = 0
return result
Output:
Recursion Example Results
1
3
6
10
15
21
Scope of Variables
All variables in a program may not be accessible at all locations in that
program. This depends on where you have declared a variable.
The scope of a variable determines the portion of the program where you can
access a particular identifier. There are two basic scopes of variables in Python
Global variables
Local variables
return total;
Output:
Inside the function local total : 30
Outside the function global total : 0
30
Modules
A module allows you to logically organize your Python code. Grouping
related code into a module makes the code easier to understand and use. A
module is a Python object with arbitrarily named attributes that you can bind
and reference.
Simply, a module is a file consisting of Python code. A module can define
functions, classes and variables. A module can also include runnable code.
The Python code for a module named aname normally resides in a file
named aname.py.
Here is an example of a simple module, support.py-
def print_func( par ):
print "Hello : ", par
return
Importing Modules
The import Statement
You can use any Python source file as a module by executing an import
statement in some other Python source file. The import has the following syntax
import module1[, module2[,... moduleN]
When the interpreter encounters an import statement, it imports the
module if the module is present in the search path. A search path is a list of
directories that the interpreter searches before importing a module. For example,
to import the module support.py, you need to put the following command at the
top of the script-
import support
support.print_func("Zara")
Variables in Module
The module can contain functions, as already described, but also variables
of all types (arrays, dictionaries, objects etc):
Example
Save this code in the file mymodule.py
person1 = {
"name": "John",
"age": 36,
"country": "Norway"
}
Example
Import the module named mymodule, and access the person1 dictionary:
31
import mymodule
a = mymodule.person1["age"]
print(a)
Output: 36
Naming a Module
You can name the module file whatever you like, but it must have the file
extension .py
Re-naming a Module
You can create an alias when you import a module, by using the as
keyword:
Example
Create an alias for mymodule called mx:
import mymodule as mx
a = mx.person1["age"]
print(a)
Output: 36
This provides an easy way to import all the items from a module into the
current namespace; however, this statement should be used sparingly.
Locating Modules
When you import a module, the Python interpreter searches for the
module in the following sequences-
The current directory.
If the module is not found, Python then searches each directory in
the shell variable PYTHONPATH.
If all else fails, Python checks the default path. On UNIX, this
default path is normally /usr/local/lib/python3/.
The module search path is stored in the system module sys as the sys.path
variable. The sys.path variable contains the current directory, PYTHONPATH,
and the installation-dependent default.
set PYTHONPATH=/usr/local/lib/python
Money = 2000
def AddMoney():
# Uncomment the following line to fix the code:
# global Money
Money = Money + 1
print (Money)
AddMoney()
print (Money)
Packages in Python
A package is a hierarchical file directory structure that defines a single
Python application environment that consists of modules and subpackages and
sub-subpackages, and so on.
35
Consider a file Pots.py available in Phone directory. This file has the
following line of source code-
def Pots():
print ("I'm Pots Phone")
Similarly, we have other two files having different functions with the same
name as above.
They are –
Phone/Isdn.py file having function Isdn()
Phone/G3.py file having function G3()
Now, create one more file __init__.py in the Phone directory
Phone/__init__.py
To make all of your functions available when you have imported Phone,
you need to put explicit import statements in __init__.py as follows-
from Pots import Pots
from Isdn import Isdn
from G3 import G3
After you add these lines to __init__.py, you have all of these classes
available when you import the Phone package.