1

I'm reading a file, chomping the line endings. I have this code.

def strip_line(read_me=file_opened_for_reading):
    return (line.strip('\n') for line in read_me)

with open('readme.txt', 'r') as file_opened_for_reading:
    stripped_lines = strip_line()
    [line for line in stripped_lines]

this doesn't work because the file is not opened

Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in strip_line
ValueError: I/O operation on closed file

but can be fixed by passing 'file_opened_for_reading' as below

with open('readme.txt', 'r') as file_opened_for_reading:
    lines = strip_line(file_opened_for_reading)
    [line for line in lines]

It makes sense that the file_opened_for_reading needs to be passed to strip_line but I was expecting that the default set for 'read_me' would take care of that. Where have I gone wrong with my use of this keyword bit?

msw
  • 42,753
  • 9
  • 87
  • 112
user5799671
  • 223
  • 2
  • 8

1 Answers1

3

The default argument file_opened_for_reading is defined during the first encounter of def strip_line (and only once!) and that is before your read the actual file, so strip_line never "sees" your opened file (thus the error).

The default argument should not be mutable, see http://docs.python-guide.org/en/latest/writing/gotchas/ or "Least Astonishment" and the Mutable Default Argument

Edit: You could define read_me='readme.txt' as default argument and open the file inside the function strip_line.

Community
  • 1
  • 1
bastelflp
  • 9,362
  • 7
  • 32
  • 67