Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

You are a fluke of the universe; you have no right to be here.


comp / comp.lang.python / Re: Best use of "open" context manager

SubjectAuthor
o Re: Best use of "open" context managerThomas Passin

1
Subject: Re: Best use of "open" context manager
From: Thomas Passin
Newsgroups: comp.lang.python
Date: Sat, 6 Jul 2024 13:40 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!fu-berlin.de!uni-berlin.de!not-for-mail
From: list1@tompassin.net (Thomas Passin)
Newsgroups: comp.lang.python
Subject: Re: Best use of "open" context manager
Date: Sat, 6 Jul 2024 09:40:49 -0400
Lines: 74
Message-ID: <mailman.7.1720273834.2981.python-list@python.org>
References: <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com>
<95527a92-d7ec-4a97-b858-25ac03847040@tompassin.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Trace: news.uni-berlin.de GysGj86h/K6xQv0r+4Fn9wYV1YLy6/IN8DUsOxUM1OvA==
Cancel-Lock: sha1:oLzd1nmoI0efLAB76LgSD9TSoTw= sha256:ndTmb1yw6CXRcvpOSp2X8jXadHSGvqKkuu1r5kELW2A=
Return-Path: <list1@tompassin.net>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=tompassin.net header.i=@tompassin.net header.b=kWzpsi6+;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.041
X-Spam-Evidence: '*H*': 0.92; '*S*': 0.00; 'this:': 0.03; '(which':
0.04; 'e.g.': 0.07; 'action,': 0.09; 'else:': 0.09; 'memory.':
0.09; 'valueerror:': 0.09; 'decreases': 0.16; 'filename': 0.16;
'pythonic': 0.16; 'received:10.0.0': 0.16; 'received:64.90': 0.16;
'received:64.90.62': 0.16; 'received:64.90.62.162': 0.16;
'received:dreamhost.com': 0.16; 'targeted': 0.16; 'wrote:': 0.16;
'to:addr:python-list': 0.20; 'closed': 0.22; 'ran': 0.22; 'code':
0.23; 'lines': 0.23; 'seems': 0.26; 'manager,': 0.26; 'leave':
0.27; 'error': 0.29; 'header:User-Agent:1': 0.30; 'attempt': 0.31;
'am,': 0.31; 'modify': 0.31; 'context': 0.32; 'python-list': 0.32;
'received:10.0': 0.32; 'received:mailchannels.net': 0.32;
'received:relay.mailchannels.net': 0.32; 'but': 0.32; 'there':
0.33; 'header:In-Reply-To:1': 0.34; 'work,': 0.36; 'really': 0.37;
'using': 0.37; 'file': 0.38; 'could': 0.38; 'put': 0.38; 'read':
0.38; 'text': 0.39; 'block': 0.39; 'program.': 0.40; 'something':
0.40; 'want': 0.40; 'should': 0.40; 'kept': 0.61; 'skip:o 10':
0.61; 'here': 0.62; 'skip:o 20': 0.63; 'header:Received:6': 0.67;
'received:64': 0.67; 'sequence': 0.69; 'small,': 0.69; 'within':
0.69; 'suite': 0.71; 'exceptions': 0.84; 'forgot': 0.84;
'readability.': 0.84; 'rob': 0.84; 'subject:manager': 0.84;
'subject:open': 0.84; 'violates': 0.84; 'loses': 0.91; 'race':
0.93
X-Sender-Id: dreamhost|x-authsender|tpassin@tompassin.net
ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1720273250; a=rsa-sha256;
cv=none;
b=nplW9RR2FEtLkW5vYPm548kcpw1fitJUFy5jlX7a1W/FmTl4OqWPfZorWiOCS5a8Htn4/4
Tu3g3N3s5K9UeR74TZzg/FQ+YHGujnijKXx33GgmOOc7ik0+UF2I3VyPl2yOt8JymGTwxt
5wp94SoJoij1y/AXJdtBOFZGcltTOmkFIxHEqwl+REbPb7WHrF21AXxV3c46ltjdGE+Ngt
SRryxcDaoCrlm+aMcH2yxBZ3+lSZJEAbgexrC9sZPe5cF4bOksW23c+Z++jPEOnpxkMES4
O++8Yrd7VRCiF3MVbnWiPEwKxlXm4BqDC2XWIJpXfvmjDyiLTSafVIC9qj0Fdg==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
d=mailchannels.net; s=arc-2022; t=1720273250;
h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
to:to:cc:mime-version:mime-version:content-type:content-type:
content-transfer-encoding:content-transfer-encoding:
in-reply-to:in-reply-to:references:references:dkim-signature;
bh=hen/9zZMc7ydZYQDbEoVstY9rbN46rUeD9hdJsgRtKQ=;
b=QLCpnOkfD+1r2NMc+9MT8Ebe14ty5SsJpBFMHJ2zRUUXpsAFt9kpjuqfHxRYa7FmF6pmMk
G1X/ONjRJ2CbkynxoOkitRLCixCmsHZvvys06v3vmmVkRohk88XmYfdMlWft0BmuyMLakI
A41Nwt/lj18Cm5GilVwYhXYWKZid09xHLAOMqoZqHLkQyGmBgmgPHXku/o8YzryZZ6DuOc
6Fv4HxIEWVLpHxAl/lUXwU9L5sl4Rfo30mIP+IkJGs7hRxBa0lITNFrvWmP+Kw0Fqt75IM
bTr0gWK/aiHl/3UO6Ni/C6q6V43BWs1eXQZ5aD0UeU4kNCp0GRnwD8n9u5N34A==
ARC-Authentication-Results: i=1; rspamd-6db77b4858-5tpt4;
auth=pass smtp.auth=dreamhost smtp.mailfrom=list1@tompassin.net
X-Sender-Id: dreamhost|x-authsender|tpassin@tompassin.net
X-MC-Relay: Neutral
X-MailChannels-SenderId: dreamhost|x-authsender|tpassin@tompassin.net
X-MailChannels-Auth-Id: dreamhost
X-Wipe-Chemical: 748f59fa73d0cf8f_1720273250923_1042851786
X-MC-Loop-Signature: 1720273250922:2463889524
X-MC-Ingress-Time: 1720273250922
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tompassin.net;
s=dreamhost; t=1720273250;
bh=hen/9zZMc7ydZYQDbEoVstY9rbN46rUeD9hdJsgRtKQ=;
h=Date:Subject:To:From:Content-Type:Content-Transfer-Encoding;
b=kWzpsi6+J/W1QgmQHO6OYkzBaag+lAVnuBGN42g94ewt6WU+5rYbol1Ot4ceLFZG9
8ZkMVkOyXFEp+I6fGMrR2dg4A9TJTnKo0XmIabpuaZxjVXsVikkHSjG5NsrYcd9Exx
Z+L0SPwj0bFx0+MLCM1wI/FkBY78FDijUb36J3qSOmXhO95R1f3fjn0Iajlms7TdkW
uP6bsxwYmnRj43BRmja0Xm0gFvb4RSZBaG+5T1X0MDKwtOfgBImCdp0RcMikYCVzfy
lIm3Ak6G/0mt+G7jz7zbjyD23iT+LIIhjfadfmXn/KMFfLuBgrv2DXgqw//qeqZDoC
vEzo6kgUt0hxw==
User-Agent: Mozilla Thunderbird
Content-Language: en-US
In-Reply-To: <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com>
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <95527a92-d7ec-4a97-b858-25ac03847040@tompassin.net>
X-Mailman-Original-References: <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com>
View all headers

On 7/6/2024 6:49 AM, Rob Cliffe via Python-list wrote:
> 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?

I usually read the file into a sequence of lines and then leave the
open() as soon as possible. Something like this:

FILENAME = 'this_is_an_example.txt'
lines = None
if os.path.exists(FILENAME):
with open(FILENAME) as f:
lines = f.readlines()
# do something with lines

Of course, if you want to read a huge number of lines you will need to
be more thoughtful about it. Or make all the processing within the
open() block be a function. Then you just have one more line in the block.

1

rocksolid light 0.9.8
clearnet tor