1
votes

I am trying to open file and look for values. If the value doesn't exist, the program will display error message and quit, otherwise will return the value. If the file does not exist, it will handle the IOError. Here is my code snippet

def findValue(value):
    try:
        myfile = open(file, "r")
        try:
            for line in myfile:
                if value in line:
                    line = do_something
                    return line
        finally:
            myfile.close()

    except IOError:
        print "File does not exist!"
        sys.exit()

    except None as e:
        print "Value not found in file"
        sys.exit()

When the value does not exist, I will always get None, I guess am missing something here but can't see it! Any tips?

3
Python is case-sensitive: value and Value are different. - cdarke
Ok I fixed it as I have it in my code and actually I am looking for something else and value here to show example, in my code it has different parameter name :) - Odin
You need no try/except for this code snippet. First, take the good habit of opening your files using with statement : docs.python.org/2/reference/…. Second, since you return any line found, you can be sure no value is found if the control reaches the end of the for loop thus no try/catch needed there either. - Arthur Hv
Guys I do use with as well :) I just didn't want to copy and clean my code, I basically wrote fast a new one that resembles the logic am doing! Thanks - Odin
Do you not want None? - Peter Wood

3 Answers

2
votes

You can use next which raises a StopIteration exception if it doesn't find anything:

try:
    with open(filename) as myfile:
        return next(line for line in myfile
                    if value in line)
except StopIteration:
    print "Value not found in file"
1
votes

It is worthwhile understanding why the original stub code has a problem.

try:                                                                             
            for line in myfile:                                                          
                if value in line:                                                        
                    line = "found line"                                                  
                    return line

This returns line if line is found. But what happens if line is not found? After iterating through myfile and value hasn't been found no error is generated so you will not trigger the except clause. Your findvalue() will implicitly return None. A minor tweek to your code fixes the issue: add a return not found string:

for line in myfile:                                                          
    if value in line:                                                        
        line = "found line"                                                  
        return line                                                          
return "Value not found in file" #or print this out. If you print this out rather than return a value the function will implicitly return a None.

and remove the except None as e: block

If you really want to raise an error then replace return "Value not found in file" with raise ValueError and replace except None as e with except ValueError as e.

0
votes

A for...else flow might be useful here, it lets you execute code in the case the for loop has reached its end (doc):

#!/usr/bin/env python2

def findValue(value):
    with open('test_file', "r") as myfile:
        for line in myfile:
            if value in line:
                #line = do_something
                return line
        else:
            raise ValueError, "Value not found in file"

print findValue('a')
findValue('z')

Test file content:

$ cat test_file 
abc
def

Script output:

$ ./test_script2.py
abc

Traceback (most recent call last):
  File "./test_script2.py", line 16, in <module>
    findValue('z')
  File "./test_script2.py", line 11, in findValue
    raise ValueError, "Value not found in file"
ValueError: Value not found in file

And of course, if you replace 'test_file' by a non-existing file, python will raise a IOError.