Deutsch   English   Français   Italiano  
<mailman.8.1720278854.2981.python-list@python.org>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!news.mixmin.net!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: Richard Damon <Richard@Damon-Family.org>
Newsgroups: comp.lang.python
Subject: Re: Best use of "open" context manager
Date: Sat, 6 Jul 2024 11:01:11 -0400
Lines: 92
Message-ID: <mailman.8.1720278854.2981.python-list@python.org>
References: <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com>
 <a4021aa1-1d0a-4e15-9976-c360ca2abe3d@Damon-Family.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
X-Trace: news.uni-berlin.de iiVTW9QukCAkrbMrQ/NqLgris7S/QuiWe8B+YrvfDPBQ==
Cancel-Lock: sha1:u/qOBgx3Ak0Dw+6oGGpG2W3f35M= sha256:/zUjJqH83zURsjMWF6JABC3Py+UQfRn1GpnMezIY5g4=
Return-Path: <Richard@Damon-Family.org>
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=Damon-Family.org header.i=richard@damon-family.org
 header.b=bWEuGDYz; dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.094
X-Spam-Evidence: '*H*': 0.82; '*S*': 0.00; 'this:': 0.03; '(which':
 0.04; 'e.g.': 0.07; 'action,': 0.09; 'damon': 0.09; 'else:': 0.09;
 'memory.': 0.09; 'valueerror:': 0.09; 'decreases': 0.16;
 'from:addr:damon-family.org': 0.16; 'from:addr:richard': 0.16;
 'from:name:richard damon': 0.16; 'message-id:@Damon-Family.org':
 0.16; 'pythonic': 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; 'function': 0.27;
 'sense': 0.28; '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; 'but': 0.32; 'there': 0.33; 'header:In-Reply-
 To:1': 0.34; 'running': 0.34; 'work,': 0.36; 'really': 0.37;
 'using': 0.37; 'received:192.168': 0.37; 'file': 0.38; 'could':
 0.38; 'put': 0.38; 'read': 0.38; 'text': 0.39; 'program.': 0.40;
 'wishes': 0.40; 'something': 0.40; 'want': 0.40; 'should': 0.40;
 'best': 0.61; 'kept': 0.61; 'skip:o 10': 0.61; 'skip:\xc2 10':
 0.62; 'here': 0.62; 'richard': 0.64; 'well': 0.65; 'factor': 0.69;
 'small,': 0.69; 'suite': 0.71; '8bit%:100': 0.76; 'documented':
 0.76; 'exceptions': 0.84; 'forgot': 0.84; 'readability.': 0.84;
 'received:74.208.4.197': 0.84; 'rob': 0.84; 'subject:manager':
 0.84; 'subject:open': 0.84; 'violates': 0.84;
 '\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0': 0.84; 'loses': 0.91;
 'line,': 0.93; 'race': 0.93
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Damon-Family.org;
 s=s1-ionos; t=1720278851; x=1720883651; i=richard@damon-family.org;
 bh=nUqeRnbAxp3qBP+3fEj6VGid1pB2+woPpdogABR+nYg=;
 h=X-UI-Sender-Class:Message-ID:Date:MIME-Version:Subject:To:
 References:From:In-Reply-To:Content-Type:
 Content-Transfer-Encoding:cc:content-transfer-encoding:
 content-type:date:from:message-id:mime-version:reply-to:subject:
 to;
 b=bWEuGDYzZ3uk1HZ81uZQHYQs0IG1Y5BYsjgUsJCb/LO9Du+jiYu3xo7hb8IWqcRZ
 lcx8BV59grRV5Tu2W+swJ/fWy1VvQOff/bTyAqNmn1pCcP1WCpCnjkVTcdQt0gYht
 t3HnjqhKDVCIk+UPsWaZWs/Em6RMHXVHs5MeHNbq4Pbqjnzu1AgZJQ6sWnyKY8UjH
 G2GiTMXifrH3EYLHtjIwab/yFnjSVKpfLsX5lzN937WrhI0Wkyf/QplNVPf41E+Gn
 Koqe+TRIf0Bpg7FPiNMFTiYhyoyaP9nbBxveHMwtlZjnbtgBJ7/IYVQhNboP21Eau
 8rtO2P00RIrJ3WbwVw==
X-UI-Sender-Class: 55c96926-9e95-11ee-ae09-1f7a4046a0f6
User-Agent: Mozilla Thunderbird
Content-Language: en-US
In-Reply-To: <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com>
X-Provags-ID: V03:K1:EHFLRceSm9NG6/bqYNYQkgkKzsFPhtvXHZuwR/4wGXVo6K7BZim
 JsOWObJn6o/iSi8/hHwv4PEy770+2tPo2QqcvCpuZOj1YKLByrb0+JbnsdPwsCRK6OXJKTJ
 lPmqC24Xt/XrSEj3b4SDMCx1eKCgH1Go7WXlYjKsM0SfB05wVCjRWpcapMuuwEQyeNX82vn
 szJJNwubVZWhK9E4kvKSw==
X-Spam-Flag: NO
UI-OutboundReport: notjunk:1;M01:P0:Qrk2ixZuCbs=;RGwMxE8RJk5FYHWin9x8HQitB86
 5jkxXGUNIImoHjCTenIccoJxlCF+g9YZaik2F9E32LRQ7rn5OBkcPuBiqS5bhVkfI3tbjAbB1
 86N9qs5DN0TOYFEfBKHymZr/L/LiHg8WCIUE42As0fVsNl8YENNVS9w7psCTisPcliTT0MPf4
 VpIH3TpxU5032uwbseKhfdfZZrFH1e8C/mZ5Pgse+BQL49cmP2l60rTwBlDU3nJa1Y3xWRChf
 5soizfqMasgyzJTsYzOSuUE15r22E8Ww1YjRIbs6/nqHsf5AsW7mWtBfPI1i0VY+/3utqiCPZ
 a3NdIqZobFXlsvQgxocsLTB4Y1S80XNUpnzVghZFh414ptxEBjrwxm0AsBKPkSkNpl/d35rFo
 ti2DYjm+nNJiNyezU2KqnVmSnMlvCIxG5EXIA0ILbt7ERmowLpPCx5Ulko71NfvbE8KD5yabA
 CxISvOxUPYQwJM6ZZ5+J760O3wLjY/Q6NXATT9fOZUvUKakVLuT4QuGirWsIbdrNS5rXEMFV4
 KLsoEkozE2QHIQ2mA3GHB82bbEfBNFaRqmK5PAjz754fYgGzI39MA32rjIYwoZMrsVLfabPbu
 7PUuiCNDlN8Ew88IsZ/jUc7fXLQ6tsVEK2k7n7F+baqx+iBbubG+m2vmBdCTLwWTk4+qmDTAs
 kqezuWQMBb0WymAzTqKTzzdx+tuIwny+xE85/hzuTZz0C1pG1mRb9rm0MWxOzAIFIMucynFps
 Nh8HTYtChZGYnQqnJwjGRuw1p6Ne6WNlzk6RIXzQMfN3kDVd8g4mBY=
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: <a4021aa1-1d0a-4e15-9976-c360ca2abe3d@Damon-Family.org>
X-Mailman-Original-References: <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com>
Bytes: 8811

My thoughts is that if the "many lines of code" puts the except to far
from the try, then perhaps it would have made sense to factor out some
part there into a function.

Perhaps like:

try:
 =C2=A0=C2=A0 with open(FileName) as f:
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for ln in f{
 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 process(ln)
except FileNotFoundError:
 =C2=A0=C2=A0 print(f"File {FileName} not found:")
 =C2=A0=C2=A0 sys.exit()

Now the "process" function has been factored out and can be well
documented as to what it is doing on each line, and this code can be
documented as running process on each line of the file.

On 7/6/24 6:49 AM, Rob Cliffe via Python-list wrote:
> Consider this scenario (which I ran into in real life):
> =C2=A0=C2=A0=C2=A0 I want to open a text file and do a lot of processing=
 on the lines
> of that file.
> =C2=A0=C2=A0=C2=A0 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:
> =C2=A0=C2=A0=C2=A0 with open(FileName) as f:
> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 for ln in f:
> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 print("I do a l=
ot of processing here")
> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 # Many lines of=
 code here .....
> except FileNotFoundError:
> =C2=A0=C2=A0=C2=A0 print(f"File {FileName} not found")
> =C2=A0=C2=A0=C2=A0 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:
> =C2=A0=C2=A0=C2=A0 f =3D open(FileName) as f:
> =C2=A0=C2=A0=C2=A0 FileLines =3D f.readlines()
> except FileNotFoundError:
> =C2=A0=C2=A0=C2=A0 print(f"File {FileName} not found")
> =C2=A0=C2=A0=C2=A0 sys.exit()
> # I forgot to put "f.close()" here -:)
> for ln in File Lines:
> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 print("I do a lot of processing he=
re")
> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 # 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:
> =C2=A0=C2=A0=C2=A0 with open(FileName) as f:
> except FileNotFoundError:
> =C2=A0=C2=A0=C2=A0 print(f"File {FileName} not found")
> =C2=A0=C2=A0=C2=A0 sys.exit()
> else: # or "finally:"
> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 for ln in f:
> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 print("I do a l=
ot of processing here")
> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 # 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


=2D-
Richard Damon