Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What sort of exception when a class can't find something?

7 views
Skip to first unread message

Chris Green

unread,
Aug 31, 2023, 4:33:24 PM8/31/23
to
What sort of exception should a class raise in __init__() when it
can't find an appropriate set of data for the parameter passed in to
the class instantiation?

E.g. I have a database with some names and address in and have a
class Person that gets all the details for a person given their
name.

....
....
person.Person('Fred')
...
...


If Fred doesn't exist in the database what sort of exception should
there be? Is it maybe a ValueError?


--
Chris Green
·

Peter J. Holzer

unread,
Aug 31, 2023, 4:54:01 PM8/31/23
to
It you are going for a builtin exception, I think KeyError is the most
appropriate: It should be a LookupError, since the lookup failed and a
database is more like a mapping than a sequence.

But it would probably be best to define your own exception for that.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | h...@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"
signature.asc

Chris Angelico

unread,
Aug 31, 2023, 5:02:15 PM8/31/23
to
On Fri, 1 Sept 2023 at 06:39, Chris Green via Python-list
There's no clear answer to this, because you aren't really
constructing a Person here. So there are a few options that seem
pretty reasonable:

1) As you say, raise ValueError. The problem is the value passed in
(it's the right type, but the value wasn't found), so, ValueError.
2) KeyError. This emphasizes the fact that you're effectively looking
up in a mapping. Quite odd for a constructor though.
3) A custom RecordNotFound exception. You're doing something unusual,
so make it your own exception.

TBH I would suggest making a slightly different API:

person.Person.from_name('Fred')

ie a classmethod alternate constructor. These can most definitely
raise ValueError when the value given isn't appropriate:

>>> datetime.datetime.fromordinal(-1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: ordinal must be >= 1

and it makes good sense for a method like this to be doing lookups,
rather than construction per se. (At a technical level, it's
presumably constructing new objects.)

To help with making that decision, what happens if you construct two
Person objects for the same actual person? Would you return the same
object (ie maintain a cache and deduplicate)? Or does each one take a
snapshot of the data at the instant of construction, and thus you can
observe changes through time by constructing more? Both are reasonable
and make sense, but they lend themselves to slightly different
approaches.

ChrisA

Chris Green

unread,
Aug 31, 2023, 5:18:28 PM8/31/23
to
Several helpful replies, thank you all.

--
Chris Green
·
0 new messages