Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #196376 > unrolled thread

Best use of "open" context manager

Started byRob Cliffe <rob.cliffe@btinternet.com>
First post2024-07-06 11:49 +0100
Last post2024-07-07 03:49 +0000
Articles 2 — 2 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Best use of "open" context manager Rob Cliffe <rob.cliffe@btinternet.com> - 2024-07-06 11:49 +0100
    Re: Best use of "open" context manager (Posting On Python-List Prohibited) Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-07-07 03:49 +0000

#196376 — Best use of "open" context manager

FromRob Cliffe <rob.cliffe@btinternet.com>
Date2024-07-06 11:49 +0100
SubjectBest use of "open" context manager
Message-ID<mailman.3.1720263159.2981.python-list@python.org>
Consider this scenario (which I ran into in real life):
     I want to open a text file and do a lot of processing on the lines 
of that file.
     If the file does not exist I want to take appropriate action, e.g. 
print an error message and abort the program.
I might write it like this:

try:
     with open(FileName) as f:
         for ln in f:
             print("I do a lot of processing here")
             # Many lines of code here .....
except FileNotFoundError:
     print(f"File {FileName} not found")
     sys.exit()

but this violates the principle that a "try" suite should be kept small, 
so that only targeted exceptions are trapped,
not to mention that having "try" and "except" far apart decreases 
readability.

Or I might write it like this:

try:
     f = open(FileName) as f:
     FileLines = f.readlines()
except FileNotFoundError:
     print(f"File {FileName} not found")
     sys.exit()
# I forgot to put "f.close()" here -:)
for ln in File Lines:
         print("I do a lot of processing here")
         # Many lines of code here .....

but this loses the benefits of using "open" as a context manager,
and would also be unacceptable if the file was too large to read into 
memory.

Really I would like to write something like

try:
     with open(FileName) as f:
except FileNotFoundError:
     print(f"File {FileName} not found")
     sys.exit()
else: # or "finally:"
         for ln in f:
             print("I do a lot of processing here")
             # Many lines of code here .....

but this of course does not work because by the time we get to "for ln 
in f:" the file has been closed so we get
ValueError: I/O operation on closed file

I could modify the last attempt to open the file twice, which would 
work, but seems like a kludge (subject to race condition, inefficient).

Is there a better / more Pythonic solution?

Best wishes
Rob Cliffe

[toc] | [next] | [standalone]


#196391 — Re: Best use of "open" context manager (Posting On Python-List Prohibited)

FromLawrence D'Oliveiro <ldo@nz.invalid>
Date2024-07-07 03:49 +0000
SubjectRe: Best use of "open" context manager (Posting On Python-List Prohibited)
Message-ID<v6d38o$6dlv$3@dont-email.me>
In reply to#196376
On 6 Jul 2024 11:46:33 GMT, Stefan Ram wrote:

>>but this of course does not work because by the time we get to "for ln
>>in f:" the file has been closed so we get ValueError: I/O operation on
>>closed file
> 
> try:
>     f = open( FileName )
> except FileNotFoundError:
>     print( f"File {FileName} not found" )
>     sys.exit()
> else:
>     with f:
>         # put this into a separate function if it gets too long here.
>         for ln in f:
>             print( "I do a lot of processing here" )
>             # Many lines of code here .....

    f = open(filename, "rt")
    for ln in f :
        ... do your processing ...

1) Let the error exception be reported directly, whether it’s “file not 
found”, or “permission error”, or some other reason; why bother to handle 
it when you don’t even know what to do anyway?
2) Notice that a file open for reading automatically gets closed when it 
goes out of scope (feature of CPython and all the other good 
implementations).

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web