Exception as the primary error handling mechanism?
Steven D'Aprano
steven at REMOVE.THIS.cybersource.com.au
Wed Jan 6 00:10:28 EST 2010
On Tue, 05 Jan 2010 17:45:58 -0800, Phlip wrote:
> On Jan 5, 5:01 pm, Chris Rebert <c... at rebertia.com> wrote:
>
>> > Why can't int('nonnumeric') return None?
>>
>> Errors should never pass silently.
>
> You are saying I, as the programmer, cannot decide what is an error and
> what is a pass-thru. The decision is made for me.
Every function decides for you what is an error and what isn't.
>>> max()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: max expected 1 arguments, got 0
But I wanted it to return (sys.maxint - 7). How DARE the creator of the
language decide that it should be an error instead of returning the
arbitrary result I choose!
Not.
> (Yes yes I can write int_or_None(), etc...)
That's right. As a programmer, your job is to program. If a language
doesn't provide a function you want, write your own using the primitives
available to you.
> Here's a super easy example:
>
> { 42: 'forty two' }.get(41, None)
>
> Because I can supply a default, I can decide what is an error and what
> is .
You can ALWAYS decide what is an error.
d = {42: 'forty two'}
try:
d[41]
except KeyError:
print "All is good, no problems, dict does not contain 41"
except:
print "WARNING WARNING WARNING!!!"
print "FATAL ERROR: dict contains 41!!!"
sys.exit()
You do so by programming. As a programmer, that's your job.
> Now the equivalent in a language that does not enjoy this false "Zen":
>
> { 42: 'forty two' }[41] # returns None
Suppose you have a dict d supplied from somewhere else. You don't know
what's in it. You do this:
d[41]
and you get a result None. Does this mean that the dict looks like this?
d = {}
or like this?
d = {41: None}
> { 42: 'forty two' }.fetch(41, None) # ibid
In Python, "fetch" is spelled "get".
> { 42: 'forty two' }.fetch(41) # raises an exception
In Python, that would be spelled {42: 'forty two'}[41]
> The quicky validation is available if I _request_ it.
When you write d[41] you are requesting it. If you don't want it, use get
instead.
>> Quibbling over a mere one more line of code (or writing one short
>> function) seems a bit petty.
>
> Because that "Zen of Python" is an empty sophistry that forces me to add
> a "mere one more line of code" over and over again...
If you're writing that one line of code over and over again, that's a
good sign that you're doing it wrong and should rethink your strategy.
>> > (A related question - why can't I just go 'if record = method(): use
>> > (record)'. Why extra lines just to trap and assign the variable
>> > before using it?)
>>
>> I believe that's disallowed so as to prevent the subtle bugs seen in C
>> code which result from when someone makes a typo and omits the second
>> "=" in their `if foo == bar():` test.
>
> Don't prevent me from using a technique just because others had trouble
> with it.
Any language allows and prevents certain techniques, simply by the very
nature of the language. Every language has it's own syntax: you can't
write weakly-typed stack-based concatenative code (like Forth) in Java,
or strongly-typed dynamic object-oriented Python code in Pascal. Every
language forces the programmer to use some features and avoid others.
> And if bar() == foo is the superior technique anyway, because the ==
> happens in chronological and lexical order after the bar() call.
That makes no sense.
--
Steven
More information about the Python-list
mailing list