Pages

Sunday, June 19, 2022

Opening and Closing a file in Python

 

Open a file

Python has a built-in function open() to open a file. Opening a file can be for different purposes like reading and/or writing data. Open function returns a file object which can be used for reading, writing and/or updating data in a file. 

Syntax

fileobject = open(file, mode, buffering, encoding, errors, newline, closefd, opener)

Among all the parameters mentioned in the syntax, only file is the mandatory parameter. Open function accepts file name and returns a corresponding file object. By using this file object data from the can be read or data can be written to the file (based on the mode specified). 

file

Before we see the importance of all the parameters, let's have a look at an example using just the mandatory parameter 'file'. 

E.g.: 

1

test_file = open("test_file.txt")


In the above example, we are trying to open the text file 'test_file.txt' and read the contents of the file. 

Couple of things to note here is, 
  • We have not mentioned where the file is located. 
  • We have not mentioned the mode (i.e., read, write or update) in which the file is opened. 
If we do not mention the file location, by default Python will look for the file in the same folder where the Python program is located. 

Let's consider if the file doesn't exist on the same folder, mentioning the file name with out the location will throw 'FileNotFoundError'. 

To avoid this error, full path of the file can be specified in the open function. 

E.g.:

1

test_file = open("C:/Users/Admin/Desktop/test_file.txt")


Let's now look at the usage of the optional parameter. 

mode

This parameter is used to specify the mode in which the file is to be opened. Default value for this parameter is 'r' (read). So, if we don't mention the mode Python opens the file in read mode by default. In the above example, test_file.txt gets opened in read mode (same as below example). 

E.g.:

1

test_file = open("test_file.txt", mode = 'r')


One thing to remember here is, value for the mode is case sensitive. Mentioning 'R' instead or 'r' would result in value error (ValueError: invalid mode: 'R').

Below are the valid values for the mode parameter. 
  • 'r' - File is open for reading (default). 
  • 'w' - File is open for writing, truncates the file first. Any data that is already present in the file would be lost as soon as it is open with write mode. Creates the file if not already present. 
  • 'x' - File is open for exclusive creation, failing if the file already exists. If the purpose is to create a new file and write data, 'x' is safer option compared to 'w'.
  • 'a' - open for writing, appending to the end of file if it exists. With 'w', if the file is already present, data is cleared first. With 'a', data in the file is not cleared and any data written is added to the end of file. 
These values can be used as is for the purpose specified. There are few other valid values which can be used in combination with the above values. 

  • 'b' - binary mode, used for binary files. This is used in combination with any of the modes mentioned above. 
    • E.g.: mode = 'rb' for reading binary files. 
    • mode = 'wb' for writing binary files. 
  • 't' - text mode (default), In case of binary files, 'b' has to be explicitly mentioned. 't' is the default value and doesn't need to be mentioned if reading/writing text (i.e., String). 
    • E.g.: mode = 'r', mode = 'rt' would both work for the same purpose of reading text data.
  • '+' - open for updating (reading and writing). With the use of mode 'r', we are only able to read the data from a file and not write vice versa with 'w', 'x' and 'a'. Adding '+' would give the flexibility to do so. 
    • E.g.: mode = 'r+' would allow both read and writing data into the file. 
    • mode = 'w+' would allow both write and read data. 

buffering

Buffering is another optional parameter and determines the buffering policy while reading a file. Buffering policy is different for binary and text files. 

Default value for buffering is '-1' and works as below. 
  • For text files - Uses line buffering. 
  • For binary files - Uses buffer size in fixed chunks based on the default buffer size (can be found using io.DEFAULT_BUFFER_SIZE).
Other valid values are, 
  • '0' - To turn off the buffering. '0' is only valid in case of binary files. 
  • '1' - To select line buffering. '1' is only  valid in case of text files. 
  • Any other other integer > 1 indicates the number of bytes of a fixed size chunk buffer. 4

encoding

Encoding refers to the encoding used to encode/decode the file. This is only applicable for text files. 

Default value for encoding parameter is 'None' i.e., no encoding is ussed. 

'codecs' module has a list of supported encoding methods. Default encoding method is platform dependent (can be found using locale.getpreferredencoding()). 

errors

Errors defines how encoding and decoding errors are handled. This can only be used with text files. 

There are many standard error handlers are available (can be found under Error Handlers). Apart from these any error handling name that is generated with codecs.register_error() are also valid.

Some of the valid values are, 
  • 'strict' -  Raise a ValueError exception if there is an encoding error.
  • 'ignore' - To ignores errors. Ignoring errors could result in a data loss.
  • 'replace' - To replace the malformed data with a replacement marker (such as '?').

newline

Newline determines how a end of line is identified (Universal newlines mode). This can only be used with text files. Valid values are None, '', '\n', '\r', '\n\r'. 
  • '\n' - Line Feed (LF), used as a new line character in Unix/Mac. 
  • '\r' - Carriage Return (CR), used as a new line character in Unix.
  • '\r\n' - Carriage Return (CR) Line Feed (LF), used as a new line character in Windows. 
While reading the file if new line is specified as, 
  • None Universal newlines mode is enabled. Lines in the input can end in '\n''\r', or '\r\n', and these are translated into '\n' before being returned to the caller
  • ' ' - Universal newlines mode is enabled, but line endings are not translated before being returned to the caller.
  •  If any other valid values (i.e., '\n', '\r' or '\r\n'), input lines are only terminated by the given string, and the line endings are not translated before being returned. 
While writing the file if new line is specified as, 
  • None - Any '\n' specified will be converted to the default line separator (default can be found is os.linesep) while writing.  
  • ' ' or '\n' - No translation takes place while writing. 
  • For all other values '\n' is converted to the string specified.

 closefd

Closefd determines if the file description is to be closed or not when the file is closed. 
  • Default value for this parameter is True, File descriptor is also closed when a file is closed. 
  • False - Only file is closed and file descriptor is kept open when file is closed. 

opener

Opener parameter can be used to pass the custom opener instead of the system opener (i.e., os.open). 

Default value is None and is same as passing os.open.

Custom opener must return an open file descriptor. 

Close a file

An opened file must be closed once the file operations (i.e., read/write) are completed. 

close() method can be used to close the file. 

Syntax

fileobject.close()

close method needs to be used with the file object created from the file open(). 


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form.

Saturday, June 11, 2022

Working with Save Files - IBM i

Save files (SAVF)

Save file is a type of file in IBM  which allows saving objects (files, programs, save files etc...) and libraries. 

Creating a save file

CRTSAVF (Create Save File) is the command to create a save file. 

CRTSAVF FILE(<library name>/<save file name>) TEXT(<description>)

E.g.:

Create Save File (CRTSAVF)

Saving objects/library into a save file

SAVOBJ (Save Object) is the command to save objects into a save file. 

SAVOBJ OBJ(<objects to save>) LIB(<library where objects are present>) DEV(*SAVF) SAVF(<save file name>)

E.g.: 

Save objects into a save file (SAVOBJ)

In the above command, 
  • OBJ (Objects) parameter is used to specify the objects that need to be saved to a save file. 
  • LIB (Library) parameter is used to specify the library from which objects need to be saved. 
  • DEV (Device) parameter is used to specify the device type (*SAVF for saving into save file).
  • OBJTYPE (Object types) parameter is used to specify what object types are to be considered for saving into save file. 
    • This is very useful when we have different objects with same name and different type (*FILE, *PGM etc...) in the same library. 
    • By default *ALL is considered and all objects with the name specified against OBJ parameter are saved. 
  • SAVF (Save file) parameter is used to specify the save file name and library to which objects are saved.
These are the mandatory parameters need to enter while saving an object. There are few other additional parameters, below are some of them. 
  • TGTRLS (Target Release) parameter is used to specify the release of the operating system on which objects are to be restored to and use the objects. 
    • By default *CURRENT is considered and objects are saved with the current system's OS release. And, objects cannot be restored to any other system which is lower OS release than current system. 
  • SELECT (Select) parameter is used to Include or Omit the objects from the list of objects specified against OBJ parameter. 
  • DTACPR (Data Compression) is used to specify whether data compression is used or not.
Above command is used to save objects into a save file. There is a different command SAVLIB (Save Library), Most of the parameters of this command are same except that SAVOBJ accepts object names and object types and SAVLIB accepts library name and saves the whole library instead. 

SAVLIB LIB(<library to save>) DEV(*SAVF) SAVF(<save file name>)

E.g.:

Save library (SAVLIB) into save file

We often notice a message like 'Save file TESTSAVF in REDDYP1 already contains data. (C G)
when we run SAVOBJ or SAVLIB. This is because the save file already has the data (possibly from the SAVOBJ or SAVLIB run earlier). 

Save library into save file

Valid reply values are - 
  • C - Cancel processing, it will cancel the processing of SAVOBJ or SAVLIB command that has been run. 
  • G - Clear file and continue processing, it will clear the data already present in the save file and continue saving objects/library to the save file. 

Display Save File (DSPSAVF)

In the above example, In order to take option 'C' or 'G', we should know what's already in the save file so we can decide if it can be cleared or not. 

DSPSAVF (Display Save File) can be used to display what objects/library is saved into the save file. 

DSPSAVF FILE(<library name>/<save file name>)

E.g.: 

Display Save file (DSPSAVF)

We have one other parameter 'OUTPUT' which is '*' by default. Using '*' would display the contents of the save file on the screen. Other valid option is '*PRINT' which prints the contents of the save file into spool file. 

Restore Objects/Library from Save file

RSTOBJ (Restore Object) is the command to restore the objects saved in a save file.

RSTOBJ OBJ(<Objects to restore>) SAVLIB(<Library objects were saved from>) DEV(*SAVF) SAVF(<Save file name>) RSTLIB(<Library objects to be restored into>)

E.g.:

Rest Objects from Save file (RSTOBJ) - IBM i

In the above command, 
  • Objects (OBJ) parameter is used to specify the objects need to be restored from the save file. *ALL can be specified to restore all the objects saved, generic* (E.g.: TEST* would consider all objects starting with TEST) to restore objects starting specific text or list of object names can be specified. 
  • Saved Library (SAVLIB) parameter is used to specify the library name from which objects were saved into save file. If not sure, this can be found by using DSPSAVF command. 
  • Object Types (OBJTYPE) parameter is used to specify the objects of specific types that are to be restored from save file. *ALL is the default and restores all object types matching with OBJ.
  • Save File (SAVF) parameter is used to specify the save file name and library. 
One thing to note here is, by using the above command objects are restored into the same library from which objects were saved. This is because of the RSTLIB (Restore to library).

Default value for RSTLIB parameter is *SAVLIB which indicates to restore the objects into the same library it was saved from. For various reasons, we may need to restore the objects to a different library. In this case, we can specify the corresponding library name against RSTLIB parameter.

RSTLIB parameter in RSTOBJ

Above command (RSTOBJ) is used to restore objects saved into a save file. 

RSTLIB (Restore Library) command is used if a library was saved into a save file using SAVLIB command.

RSTLIB SAVLIB(<Library Saved>) DEV(*SAVF) SAVF(<Save file name>) RSTLIB(<Restore to library>)

E.g.:

Restore Library (RSTLIB) - IBM i

Similar to RSTOBJ, by default RSTLIB restores the library with the same name as the library saved. RSTLIB parameter to be specified with different library name if objects are to be restored into different library.

Transfer Save file from IBM i to PC

Often it is essential to transfer save file from one IBM i to another IBM i or IBM i to PC. Save file can be transferred from IBM i to PC by using FTP. 

Below is the FTP script required to transfer the save file from IBM i to PC. 

1

2

3

4

5

6

FTP <IBM i System Name>

User

Password

BIN

GET <Library>/<Save file> <Save file name>

QUIT


Open the command line/terminal in order to run the FTP connection with IBM i. 

In the above script,
  • Line - 1: FTP command to be issued followed by IBM i system name or IP address. This establishes a connection with IBM i and prompts for credentials.
  • Lines 2 & 3: IBM i credentials (User & Password) are to be entered. 
  • Line - 4: BIN command to be issued to set the representation type is Binary IMAGE. 
  • Line - 5: GET command to be issued to get the save file from IBM i library and place into PC. 
    • <Library>/<Save file> - IBM i Library name and Save file name
    • <Save file name> - Name save file to be saved with on PC. 
  • Line - 6: QUIT command to be issued to quit the FTP session.

Transfer Save file from PC to IBM i

Below is the FTP script required to transfer save file from PC to IBM i.

1

2

3

4

5

6

FTP <IBM i System Name>

User

Password

BIN

PUT <Save file name> <Library>/<Save file> 

QUIT


Open the command line/terminal in order to run the FTP connection with IBM i. 

In the above script,
  • Line - 1: FTP command to be issued followed by IBM i system name or IP address. This establishes a connection with IBM i and prompts for credentials.
  • Lines 2 & 3: IBM i credentials (User & Password) are to be entered. 
  • Line - 4: BIN command to be issued to set the representation type is Binary IMAGE. 
  • Line - 5: PUT command to be issued to put the save file from PC and place into IBM i Library. 
    • <Save file name> - Name of the save file on PC. 
    • <Library>/<Save file> - IBM i Library name and Save file name.
  • Line - 6: QUIT command to be issued to quit the FTP session.
One thing to note is if the objects were saved into save file for the higher version of the OS, Objects cannot be restored into a system which is on lower OS release (E.g.: If objects were saved for Target Release V7R4, Objects cannot be restored into V7R3 or lower).


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form. 

Tuesday, April 26, 2022

View Job Queue Info from SQL - IBM i

Job Queue

Dealing with Job Queues (JOBQ) is part of day to day life when working with IBM i. There comes many situations where we need to check if a JOBQ is Held or Released, Which subsystem the JOBQ is attached to, No of active/held/released/scheduled jobs in JOBQ, Maximum number of active jobs etc. 

Different commands (WRKJOBQ, WRKJOBQD, WRKSBSD) are available to view this information. 

There is another easier way to access this information is by using SQL view JOB_QUEUE_INFO in QSYS2 (system name - JOBQ_INFO). 

One thing to note is, User should either have read authority to the JOBQ or have one of the special authorities *JOBCTL, *SPLCTL.

This view is helpful in many different ways like, 
  • List of Job queues present in a library. 
  • List of Job queues HELD/RELEASED in a library.
  • Retrieve Subsystem a JOBQ is attached to. 
  • List of Job queues in a Subsystem. 
  • Retrieve maximum number of active jobs in a Job queue. 
  • Retrieve number of Active/Held/Released/Scheduled jobs in a Job queue. 
E.g.:

List of Job queues present in a library. 

SELECT * FROM QSYS2/JOB_QUEUE_INFO WHERE JOB_QUEUE_LIBRARY = 'PREDDY'

List of Job queues HELD/RELEASED in a library.

SELECT * FROM QSYS2/JOB_QUEUE_INFO WHERE JOB_QUEUE_LIBRARY = 'PREDDY' AND JOB_QUEUE_STATUS = 'RELEASED'

Retrieve Subsystem a JOBQ is attached to. 

SELECT SUBSYSTEM_NAME, SUBSYSTEM_LIBRARY_NAME FROM QSYS2/JOB_QUEUE_INFO WHERE JOB_QUEUE_LIBRARY = 'PREDDY' AND JOB_QUEUE_NAME = 'TESTJOBQ'

List of Job queues in a Subsystem. 

SELECT * FROM QSYS2/JOB_QUEUE_INFO WHERE SUBSYSTEM_NAME = 'TESTSBS' AND SUBSYSTEM_LIBRARY_NAME = 'PREDDY'

Retrieve maximum number of active jobs in a Job queue. 

SELECT MAXIMUM_ACTIVE_JOBS FROM QSYS2/JOB_QUEUE_INFO WHERE JOB_QUEUE_LIBRARY = 'PREDDY' AND JOB_QUEUE_NAME = 'TESTJOBQ' 

Retrieve number of Active/Held/Released/Scheduled jobs in a Job queue. 

SELECT ACTIVE_JOBS, HELD_JOBS, RELEASED_JOBS, SCHEDULED_JOBS FROM QSYS2/JOB_QUEUE_INFO WHERE JOB_QUEUE_LIBRARY = 'PREDDY' AND JOB_QUEUE_NAME = 'TESTJOBQ' 

In addition to these number of active/held/released/scheduled job information by priority can be found. 

Below are the important columns present in this view. 

JOB_QUEUE_NAME (JOBQ) - The name of the job queue.

JOB_QUEUE_LIBRARY (JOBQ_LIB) - The name of the library that contains the job queue.

JOB_QUEUE_STATUS (STATUS) - The status of the job queue. HELD (The queue is held), RELEASED (The queue is released)

NUMBER_OF_JOBS (JOBS) - The number of jobs in the queue.

SUBSYSTEM_NAME  (SUB_NAME) - The name of the subsystem that can receive jobs from this job queue. Contains the null value if this job queue is not associated with an active subsystem.

SUBSYSTEM_LIBRARY_NAME (SUBLIB_NAM) - The library in which the subsystem description resides. Contains the null value if this job queue is not associated with an active subsystem.

SEQUENCE_NUMBER (SEQNO) - The job queue entry sequence number. The subsystem uses this number to determine the order in which job queues are processed. Jobs from the queue with the lowest sequence number are processed first. Contains the null value if this job queue is not associated with an active subsystem.

MAXIMUM_ACTIVE_JOBS (MAX_JOBS) - The maximum number of jobs that can be active at the same time through this job queue entry. A value of -1 indicates *NOMAX, no maximum number of jobs is defined. Contains the null value if this job queue is not associated with an active subsystem.

ACTIVE_JOBS (ACT_JOBS) - The current number of jobs that are active that came through this job queue entry. Contains the null value if this job queue is not associated with an active subsystem.

HELD_JOBS (HELD_JOBS) - The current number of jobs that are in *HELD status. 

RELEASED_JOBS (RLS_JOBS) - The current number of jobs that are in *RELEASED status. 

SCHEDULED_JOBS (SCHED_JOBS) - The current number of jobs that are in *SCHEDULED status. 

TEXT_DESCRIPTION (TEXT) - Text that describes the job queue. Contains the null value if there is no text description for the job queue.

OPERATOR_CONTROLLED (OPR_CTRL) - Whether users with job control authority are allowed to control this job queue and manage the jobs on the queue. Users have job control authority if SPCAUT(*JOBCTL) is specified in their user profile. *NO - This queue and its jobs cannot be controlled by users with job control authority unless they also have other special authority. *YES - Users with job control authority can control the queue and manage the jobs on the queue.

AUTHORITY_TO_CHECK (ALL_AUTH) - Whether the user must be the owner of the queue in order to control the queue by holding or releasing the queue. *DTAAUT - Any user with *READ, *ADD, or *DELETE authority to the job queue can control the queue. *OWNER - Only the owner of the job queue can control the queue.


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form. 

Friday, April 15, 2022

Record Lock Info from SQL - IBM i

Record Locks

Record locks often causes the programs to crash if not handled properly. Identifying which job is locking the record is essential to resolve the issue (specially if the locking job is interactive idle for long time). 

One way of identifying the Record locks is by using the command DSPRCDLCK (Display Record Locks). 

This command accepts the below parameters and allows checking for the locks at the file, member and record level. Output of this command can only be either display or print. 

                       Display Record Locks (DSPRCDLCK)              
                                                                     
Type choices, press Enter.                                           
                                                                     
Physical file  . . . . . . . . . > TESTFILE      Name                
  Library  . . . . . . . . . . . >   PREDDY1     Name, *LIBL, *CURLIB
Member . . . . . . . . . . . . .   *FIRST        Name, *FIRST        
Record number  . . . . . . . . .   *ALL          1-4294967288, *ALL  
Output . . . . . . . . . . . . .   *             *, *PRINT           

Physical File - Name of the physical file for which record locks are to be checked. Locks can be checked only for one physical file at a time. 

Library - Library in which the physical file is present. Valid values are library name, *LIBL (default) and *CURLIB. 

Member - Name of the physical file member for which record locks are to be checked. Specific member name can be entered otherwise *FIRST (default) is considered. Record locks can be checked for only one member at a time. 

Record number - Record number can be entered for which we need to check if the specific record is locked. *ALL (default) checks for all the records in the file/member specified. 

Output - Output can either be displayed (by using * in Interactive job) or printed to spool file (by using * in Batch job or *PRINT in Interactive/Batch job).

This looks straight forward when we need to check the record locks for a single file or couple of files. And, If we need to resolve the locks manually. 

But, If we need to
  • Identify the record locks for a group of files.
  • Identify the record locks for all the members of a file. 
  • Identify the record locks for all the files in a Library.  
  • Identify the record locks by a specific Job. 
This can be easily achieved from SQL by running a query on the view RECORD_LOCK_INFO in QSYS2 (System name - RCD_LOCK). 

E.g.: 

Identify the record locks for a group of files. 

SELECT * FROM QSYS2/RECORD_LOCK_INFO WHERE TABLE_NAME IN ('TESTFILE', 'TESTFILE1', 'TESTFILE2') ;

Identify the record locks for all members of a file - Just querying for a file name (and library) would return the locks present in all members of the file. 

SELECT * FROM QSYS2/RECORD_LOCK_INFO WHERE TABLE_SCHEMA = 'PREDDY1' AND TABLE_NAME = 'TESTFILE' ;

Identify the record locks for all the files in a Library. 

SELECT * FROM QSYS2/RECORD_LOCK_INFO WHERE TABLE_SCHEMA = 'PREDDY1'  ;

Identify the record locks by a specific Job. 

SELECT * FROM QSYS2/RECORD_LOCK_INFO WHERE JOB_NAME = '123456/PREDDY/QPADEV1234' ;

Apart from these, the query can be run based on any of the columns available in the view RECORD_LOCK_INFO. 

Below are the columns present in the view. 

TABLE_SCHEMA (TABSCHEMA) - Name of the schema.

TABLE_NAME (TABNAME) - Name of the table.

TABLE_PARTITION (TABPART) - Name of the table partition or member that contains the locked record.

SYSTEM_TABLE_SCHEMA (SYS_DNAME) - System name of the schema.

SYSTEM_TABLE_NAME (SYS_TNAME) - System name of the table

SYSTEM_TABLE_MEMBER (SYS_MNAME) - The name of the member that contains the locked record.

RELATIVE_RECORD_NUMBER (RRN) - The relative record number (RRN) of the record that is locked.

LOCK_STATE (LOCK_STATE) - The lock condition for the record. Valid values are READ (The record is locked for read. Another job may read the same record but cannot lock the record for update intent. The record cannot be changed by another job as long as one job holds a read lock on the record.), UPDATE (The record is locked for update intent. Another job may read the record but may not obtain a read or update lock on it until the lock is released.) and INTERNAL (The row is locked internally for read. For a short time the operating system holds an internal lock to access the row. Another job may read the same row and may even have the row locked for update intent. However, if another job does have the row locked for update intent, the actual change of the row will not proceed until the internal lock is released.)

LOCK_STATUS (STATUS) - The status of the lock. Valid values are HELD (The lock is currently held by the job.), WAITING (The job is waiting for the lock.)

LOCK_SCOPE (LOCK_SCOPE) - The scope of the lock. Valid values are JOB, THREAD and LOCK SPACE

JOB_NAME (JOB_NAME) - The qualified job name.

THREAD_ID (THREAD_ID) - The thread that is associated with the lock. If a held lock is job scoped, returns the null value. If a held lock is thread scoped, contains the identifier for the thread holding the lock. If the scope of the lock is to the lock space and the lock is not held, contains the identifier of the thread requesting the lock. If the lock is requested but not yet available, contains the identifier of the thread requesting the lock.

LOCK_SPACE_ID (LOCKID) - When the LOCK_SCOPE column value is LOCK SPACE and the lock is being waited on by a thread, contains the lock space ID value for which the lock is being waited on. Otherwise, contains the null value.

If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form. 

Wednesday, July 28, 2021

Exception Handling in Python (try - except-else-finally)

Exception Handling in Python

Exception handling is key for any programming language. When an exception occurs Python interpreter stops execution further statements in the program. 

These exceptions could either be related to the Syntax or Data. There are many Built-in exceptions in Python and we can also define user defined exceptions. 

Exception handling in Python can be done by using try - except statements. We can also use else and finally statements depending on how we need to handle the exceptions.

Syntax:

try:

    # Executable statements

except:

    # Statements to execute in case of exception

else:

    # Statements to execute in case of no exception 

finally:

    # Statements to execute irrespective of exception or not


Let's have a look at how to use these statements with few simple examples. 

try and except

try statement should be used in combination of either except or finally. Without these, An exception would occur. 

Let's have a look at the simple division by zero exception (my favorite when it comes to checking exception handling). 

1

2

3

4

a = 10

b = 0

c = a/b

print(c)


Result

Traceback (most recent call last):

  File "/Users/Admin/PycharmProjects/pythonProject/main.py", line 3, in <module>

    c = 10/0

ZeroDivisionError: division by zero



In the above example, 
  • Line - 3: An exception (ZeroDivisionError) is occurred when attempting to divide a with b. 
    • This causes the further statements to not execute. 
We can use try and except statements to handle the exception. 

1

2

3

4

5

6

7

8

try:

   a = 10

   b = 0

   c = a/b

except:

   c = 0

 

print(c)


This is a simple example of handling the exception. 
  • Line - 1: We are using the try statement before the block of code which needs to be monitored for exception. 
    • Lines 2 - 4: Indentation to be followed for the code that should fall under the try statement. 
  • Line - 5: We are using except statement (with no specific exception type) to capture any exception.
    • Line - 6: We are initializing the variable 'c' with zero in case of exception. 
    • This can be replaced with set of statements as required and should follow the indentation. 
  • Line - 8: print statement here would execute with out any error as any exception in the division would be handled with the try and except statements. 

This is a very basic example and we are not using any exception type along with except statement. This would capture all types of exception. 

Let's have a look at different example to open a file and read the content of the file. 

1

2

3

4

notes = open("notes.txt", "r")

notes_content = notes.read()

print(notes_content)

notes.close()


Result


Traceback (most recent call last): File "/Users/Admin/PycharmProjects/pythonProject/main.py", line 1, in <module> notes = open("notes.txt", "r") FileNotFoundError: [Errno 2] No such file or directory: 'notes.txt'


In the above example, we are trying to open a file which does not exist. 
  • Line - 1: An exception is occurred while opening the file which does not exist. 
This causes the following statements to not run. 

Adding try and except statements would capture the error and execute the statements under except block. 

1

2

3

4

5

6

7

try:

   notes = open("notes.txt", "r")

   notes_content = notes.read()

   print(notes_content)

   notes.close()

except:

   print("No file named 'notes.txt'")


In the two examples shared, We are using except statement without mentioning exception type and we are executing different statements for the different exceptions. 

Let's say if the code from both the examples need to be executed as a single block and we need to act based on the exception occurred. 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

try:

   a = 10

   b = 1

   c = a/b

   print(c)

 

   notes = open("notes.txt", "r")

   notes_content = notes.read()

   print(notes_content)

   notes.close()

except ZeroDivisionError:

   c = 0

   print(c)

except FileNotFoundError:

   print("No file named 'notes.txt'")

except:

   print("Error Occurred!")


In the above example, 
  • Lines 1 - 10: try statement followed by the executable statements with the possibility of different exceptions. 
  • Line - 11: We are mentioning 'ZeroDivisionError' along with except statement. This would capture the Division by zero error and runs the block of statements mentioned under this block. 
  • Line - 14: We are mentioning 'FileNotFoundError' along with except statement. This would capture the File not found error and runs the block of statements mentioned under this block.
  • Line - 16: We are using except statement with out any specific exception type. This would capture any error except the two different types of exceptions specifically mentioned. 
Full list of exception types can be found here

else

If there are any set of statements to be executed if no exception occurred, these can be mentioned under the else statement. 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

try:

   a = 10

   b = 1

   c = a/b

   print(c)

 

   notes = open("notes.txt", "r")

   notes_content = notes.read()

   print(notes_content)

   notes.close()

except ZeroDivisionError:

   c = 0

   print(c)

except FileNotFoundError:

   print("No file named 'notes.txt'")

except:

   print("Error Occurred!")

else:

   print("No Error Occurred, Execution is complete!")


In the above example, 
  • Line - 18: We are adding else statement to the try - except. 
    • Block of statements under else would only be executed if the block of code under try is executed without any exception. 

finally

If there are any set of statements to be executed irrespective of the exceptions present or not. These statements can be mentioned under finally statement.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

try:

   a = 10

   b = 1

   c = a/b

   print(c)

 

   notes = open("notes.txt", "r")

   notes_content = notes.read()

   print(notes_content)

   notes.close()

except ZeroDivisionError:

   c = 0

   print(c)

except FileNotFoundError:

   print("No file named 'notes.txt'")

except:

   print("Error Occurred!")

else:

   print("No Error Occurred, Execution is complete!")

finally:

   print("Execution has been completed.")


In the above example, 
  • Line - 20: We are adding finally statement to try - except statements. 
    • Block of statements under finally would be executed irrespective of the exceptions in the code. 

Hope the above info was useful in understanding exception handling in Python. 


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form.

Opening and Closing a file in Python

  Open a file Python has a built-in function open() to open a file. Opening a file can be for different purposes like reading and/or writing...