1

I'm attempting to make a class object whose constructor takes in a list of files, turns each into a list of strings (one per line) and concatenates all the lists together and stores it. This class also contains a member function which outputs a random line from the list

class randline:
    def __init__(self, filename = [] ):
        #def __init__(self, filename = [] , *args):

        #for i in range(len(filename)):
        self.lines = []

        for path in filename:
           with open(path, 'r') as f:
                self.lines + f.readlines()
                f.close()

    def chooseline(self):
      if self.lines:
        return random.choice(self.lines)

def main():
#...
    try:
        generator = randline(args)
        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))

This produces the error message:

Traceback (most recent call last):
  File "./1randline.py", line 59, in <module>
    main()
  File "./1randline.py", line 53, in main
    sys.stdout.write(generator.chooseline())
TypeError: expected a character buffer object

But chooseline() produces a string from the list of concatenated file strings, doesn't it? So I'm having a hard time figuring out what the problem is.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
user2303321
  • 297
  • 2
  • 11
  • `self.lines + f.readlines()` doesn't do anything. Maybe you want `self.lines += f.readlines()` instead? – Volatility Apr 21 '13 at 00:25
  • Regarding `def __init__(self, filename = []):` -- that habit is going to get you into trouble. Don't use mutable objects like lists as default arguments -- see [here](http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument) for an explanation of why. – DSM Apr 21 '13 at 00:34
  • @DSM Thanks, What should I use instead? *filename ? – user2303321 Apr 21 '13 at 00:45

1 Answers1

1

Should be

self.lines += f.readlines() # notice the += 
# self.lines.extend(f.readlines()) is equivalent

However you can just use fileinput for this instead

import fileinput
lines = list(fileinput.input(paths))
jamylak
  • 128,818
  • 30
  • 231
  • 230