Deutsch English Français Italiano |
<mailman.7.1720273834.2981.python-list@python.org> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!2.eu.feeder.erje.net!feeder.erje.net!fu-berlin.de!uni-berlin.de!not-for-mail From: Thomas Passin <list1@tompassin.net> 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> Bytes: 8443 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.