Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

BOFH excuse #451: astropneumatic oscillations in the water-cooling


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

SubjectAuthor
o Re: Best use of "open" context managerOscar Benjamin

1
Subject: Re: Best use of "open" context manager
From: Oscar Benjamin
Newsgroups: comp.lang.python
Date: Sat, 6 Jul 2024 11:57 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: oscar.j.benjamin@gmail.com (Oscar Benjamin)
Newsgroups: comp.lang.python
Subject: Re: Best use of "open" context manager
Date: Sat, 6 Jul 2024 12:57:37 +0100
Lines: 65
Message-ID: <mailman.6.1720267071.2981.python-list@python.org>
References: <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com>
<CAHVvXxSKiws7R9v_3z9_8TP-Zsbw9MaXsNKxThLP4odWAcTUCA@mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
X-Trace: news.uni-berlin.de P4P1N+JM1eibtC19p5A9fQKUz1xIyuQ//UAD2D4wOGUg==
Cancel-Lock: sha1:WGqCOUrDmLSkOgLcOA7odtf72yk= sha256:0vaUloFrViejZEZ46PTMzlkKVAm2zc8UY+xzLfdGcaQ=
Return-Path: <oscar.j.benjamin@gmail.com>
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=gmail.com header.i=@gmail.com header.b=h7r0+GWO;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.024
X-Spam-Evidence: '*H*': 0.95; '*S*': 0.00; 'this:': 0.03; '(which':
0.04; 'jul': 0.04; 'improvement': 0.05; 'e.g.': 0.07; 'action,':
0.09; 'situations': 0.09; '2024': 0.16; 'applies': 0.16;
'decreases': 0.16; 'exception.': 0.16; 'filename': 0.16;
'instead.': 0.16; 'intention': 0.16; 'readability': 0.16;
'received:mail-lf1-x131.google.com': 0.16; 'targeted': 0.16;
'wrote:': 0.16; 'larger': 0.17; 'code.': 0.17; 'bug': 0.19;
'to:addr:python-list': 0.20; 'exception': 0.22; 'ran': 0.22;
'sat,': 0.22; 'code': 0.23; 'lines': 0.23; 'function': 0.27;
'wrong': 0.28; 'error': 0.29; 'raise': 0.31; 'think': 0.32;
'fine.': 0.32; 'python-list': 0.32; 'to:name:python': 0.32;
"wouldn't": 0.32; 'message-id:@mail.gmail.com': 0.32; 'but': 0.32;
'there': 0.33; 'particular': 0.33; 'header:In-Reply-To:1': 0.34;
'received:google.com': 0.34; 'from:addr:gmail.com': 0.35; 'class':
0.37; 'file': 0.38; 'way': 0.38; 'could': 0.38; 'least': 0.39;
'text': 0.39; 'handle': 0.39; 'use': 0.39; 'block': 0.39;
'program.': 0.40; 'something': 0.40; 'want': 0.40; 'try': 0.40;
'should': 0.40; 'kept': 0.61; 'skip:o 10': 0.61; 'here': 0.62;
'clear': 0.64; 'mainly': 0.64; 'dedicated': 0.65; 'bad': 0.67;
'small,': 0.69; 'raised': 0.70; 'suite': 0.71; 'catch': 0.84;
'catching': 0.84; 'exceptions': 0.84; 'oscar': 0.84;
'readability.': 0.84; 'rob': 0.84; 'subject:manager': 0.84;
'subject:open': 0.84; 'violates': 0.84; 'worry': 0.95
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20230601; t=1720267069; x=1720871869; darn=python.org;
h=to:subject:message-id:date:from:in-reply-to:references:mime-version
:from:to:cc:subject:date:message-id:reply-to;
bh=+Es43NsLZauxi5dBtbbpTU33wQHk4PB5VqO67LSluz4=;
b=h7r0+GWOmoaKQ6RIt2Z1CyGGUE6SaoH2UsmJmvHywwWzKcvYnKCyR71Aa1OJ76hS02
cHjjvtp9nMF0EcrsmEVr+lDRIu+naCfw0GewiopgkOSsBlJNypJZ1onvrdA7+bq5+JWm
tEGQBQfqJPQecS8xNEXiXtrJGCNxT8Gep0HZMS3xAqxKJnzWq/Aj1JA42YH8EsFwpPI/
W9FgreQvXa4jiTyODJQFWQ0p54UrXxziKMm/05Dv8HBGwooIGBMi3BjlfEhH75Is9Myl
wZz+OmTqlVbs5b6nzZRtgh+yd6DafAlD+kFYeadq3ZVNM9ban80km556BbGgJmp/fpnD
L2Zw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20230601; t=1720267069; x=1720871869;
h=to:subject:message-id:date:from:in-reply-to:references:mime-version
:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
bh=+Es43NsLZauxi5dBtbbpTU33wQHk4PB5VqO67LSluz4=;
b=mowb+oq+hI6CL0VJLqZB7T/oh9tx1AO87wNMDsnsfPxlFYbSkR1LDSqL933S2zYUl7
pEVv/aUiwQUh+y3LDsw4YKJSHA/nbpVvHXyqfvC58lms8g9nSHGU2m7D0R9MKT5akQiG
d6Yha1ZEyLv57dcCFonKaBRpYRMiMY3VhsjP93DAe6/uMpnayrFbOiUFm9mwodqsv0ab
Yco2udVW4Kyb4s5jGd9h1lwA+JswUni0tcEelzeAaexRdLOv9VLsCyfIdvkseps6Jl8i
e9EMCLKI8F+kVMS62dvwdQHf5Q9PQKUiQWUMcmRvN2MOLi7GLzZkoWMLU1Xlv7h9grut
HtVQ==
X-Gm-Message-State: AOJu0Yxx1QhrwBsnde+qXG1XfpM4BFGuTfyn0rVw7rIY98jseQmhoVLN
qwmS11CPdhl379cz5OVeN16iWr9qzM8gxSXxPdvE12R4iqDc0nAzhSKgaBI/C8Q1yX3/sRhQWeI
9cAFy7x84nnc6BpSYU95GUqPE5+2n0Omb
X-Google-Smtp-Source: AGHT+IHh54zD3Tkz+IzrDByK7GqDaUhMviGeg0adKZyWTfhWkZIioCYHNAXs/OJkcGSg7vRhEnK7u0+jFhu7LMLL/Q4=
X-Received: by 2002:ac2:5472:0:b0:52c:df74:1577 with SMTP id
2adb3069b0e04-52ea06a77d9mr5708593e87.45.1720267068973; Sat, 06 Jul 2024
04:57:48 -0700 (PDT)
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: <CAHVvXxSKiws7R9v_3z9_8TP-Zsbw9MaXsNKxThLP4odWAcTUCA@mail.gmail.com>
X-Mailman-Original-References: <954c4ca8-cf37-4482-a1be-46d39cb503f9@btinternet.com>
View all headers

On Sat, 6 Jul 2024 at 11:55, Rob Cliffe via Python-list
<python-list@python.org> 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.

This is catching a targeted exception (FileNotFoundError) so I think
it is fine. If the intention is just to call sys.exit() on error then
I wouldn't worry too much about having too much code in the try. Just
make sure that you do this in any other place where you open a file as
well.

One possible improvement is that you could catch the exception and use
its filename attribute:

except FileNotFoundError as e
print(f"File {e.filename} not found")

That way if you did catch the wrong FileNotFoundError then at least
you print the correct filename.

Alternatively:

except FileNotFoundError as e
if e.filename != FileName:
raise # re-raise if not the intended exception
print(f"File {e.filename} not found")

For readability I would just move the many lines of code into a
separate function.

The reason to avoid having too much code in the try mainly applies to
situations where you are going to do something other than call
sys.exit() and the exception is overly generic like ValueError or
TypeError. If the exception can easily be raised by a bug or something
other than the intended cause then it is bad to catch exceptions
around a larger block of code.

If it is expected that the caller of a function might have good reason
to catch the exception and handle it somehow then it is better to make
a dedicated exception class and raise that instead. When there is only
one place in the code that raises a particular exception type and only
one place that catches it then it is usually going to be clear that
you are catching the expected exception.

--
Oscar

1

rocksolid light 0.9.8
clearnet tor