porting Python 2 program to Python 3, random line generator

11,145

Solution 1

This line is incorrect syntax:

except IOError as (errno, strerror):

The correct form is:

except IOError as err:

then you can examine err for attributes like errno, etc.

I'm not sure where you got the original line from, it isn't valid Python 2.x syntax either.

Solution 2

The line "except IOError as (errno, strerror)" relies on a the little used obscure fact that exceptions in Python 2 are iterable, and that you can iterate over the parameters given to the exception by iterating over the exception itself.

This of course breaks the "Explicit is better than implicit" rule of Python and has as such been removed in Python 3, so you can no longer do that. Instead do:

except IOError as e:
   errno, strerror = e.args

This is clearer and works under all versions of Python.

Share:
11,145
Shubham
Author by

Shubham

https://www.tindie.com/stores/sg92/

Updated on June 19, 2022

Comments

  • Shubham
    Shubham almost 2 years

    I have a random line generator program written in Python2, but I need to port it to Python3. You give the program the option -n [number] and a file argument to tell it to randomly output [number] number of lines from the file. Here is the source for the program:

    #!/usr/bin/python
    
    import random, sys
    from optparse import OptionParser
    
    class randline:
        def __init__(self, filename):
            f = open(filename, 'r')
            self.lines = f.readlines()
            f.close()
    
        def chooseline(self):
            return random.choice(self.lines)
    
    def main():
        version_msg = "%prog 2.0"
        usage_msg = """%prog [OPTION]... [FILE] [FILE]...
    
    Output randomly selected lines from each FILE."""
    
        parser = OptionParser(version=version_msg,
                              usage=usage_msg)
        parser.add_option("-n", "--numlines",
                          action="store", dest="numlines", default=1,
                          help="output NUMLINES lines (default 1)")
        options, args = parser.parse_args(sys.argv[1:])
    
        try:
            numlines = int(options.numlines)
        except:
            parser.error("invalid NUMLINES: {0}".
                         format(options.numlines))
        if numlines < 0:
            parser.error("negative count: {0}".
                         format(numlines))
        if len(args) < 1:
            parser.error("input at least one operand!")
    
        for index in range(len(args)):
            input_file = args[index]
            try:
                generator = randline(input_file)
                for index in range(numlines):
                    sys.stdout.write(generator.chooseline())
            except IOError as (errno, strerror):
                parser.error("I/O error({0}): {1}".
                            format(errno, strerror))
    
    if __name__ == "__main__":
        main()
    


    When I run this with python3:

    python3 randline.py -n 1 file.txt
    

    I get the following error:

      File "randline.py", line 66
        except IOError as (errno, strerror):
                          ^
    SyntaxError: invalid syntax
    

    Can you tell me what this error means and how to fix it?

    Thanks!

  • Shubham
    Shubham over 12 years
    Thanks for the solution! it works! hmm thats odd because the program works with python2...
  • yantrab
    yantrab over 12 years
    Hmm, maybe it is valid Python 2.x syntax, but it's very strange.
  • jfs
    jfs over 12 years
    @Ned Batchelder: Exceptions are sequences in Python 2.x. I guess as (a, b) performs tuple unpacking on the exception object. I see @Lennart Regebro already answered it.