The Samurai Principle

Tim Chase python.list at tim.thechases.com
Tue Sep 7 15:45:04 EDT 2010


On 09/07/10 13:53, Phlip wrote:
> On Sep 7, 11:36 am, Tim Chase<python.l... at tim.thechases.com>  wrote:
>
>>> And no it's not "much clearer". Exceptions are for catastrophic errors
>>> that the caller should care not to handle. A "record not found" is not
>>> a catastrophe.
>>
>> Exceptions are not limited to catastrophic errors, simply
>> exceptional (not the common) cases.  E.g. iterators raising
>> StopException when exhausted.
>
> Exceptions are not "because we should only return one type of thing".
> They are for situations which the caller should care not to handle.
> Exceptions are for propagating. A "record not found" is an exemplary
> example of a situation the caller _should_ handle.

Um...first you state "Exceptions are for catastrophic errors that 
the caller should not care to handle. A 'record not found' is not 
a catastrophe" and then you contradictingly go on to state "A 
'record not found' is an exemplary example of a situation the 
caller _should_ handle".  I'm not sure I follow your logic here. 
  Exceptions allow both (1) the ability to handle the exceptional 
condition locally if you want to (including suppressing it) and 
(2) propagate the exception if you want to make the caller handle it.

And if you really want, you can just subclass QuerySet to provide 
your own get_or_none() method to return your sentinel.

>>     items = list(MyModel.objects.filter(...))
>>     if len(items) == 1:
>>       do_something(items[0])
>>     else:
>>       what_the(...)
>
> Both your version and mine read an entire cursor. But mine only rezzed
> the first object, whereas yours rezzed every object in the cursor,
> just to throw most of them away!

If a .get() returns more than one object (non-unique criteria are 
used), what _should_ it return?  Agreed, if it pulls back a 
bajillion records, that's bad, so if you're concerned your 
conditions might do that despite the expectation they bring back 
1-and-only-1 (.get() currently raises an exception if it brings 
back more than one result db/models/query.py around line 342 
where MultipleObjectsReturned is raised), then I'd just slice them:

   items = list(MyModel.objects.filter(...)[:1])
   if items:
     do_something(items[0])
   else:
     what_the(...)

-tkc






More information about the Python-list mailing list