Raise X or Raise X()?

Stefan Behnel stefan_ml at behnel.de
Mon Mar 12 14:52:49 CET 2012


Irmen de Jong, 11.03.2012 21:37:
> On 11-3-2012 20:04, bvdp wrote:
>> Which is preferred in a raise: X or X()? I've seen both. In my specific case I'm dumping out of a deep loop:
>>
>> try:
>>   for ...
>>     for ...
>>       for ...
>>         if match:
>>            raise StopInteration()
>>          else ...
>>
>> except StopInteration:
>>    print "found it"
> 
> "raise X" is a special case of the 3-args raise. Effectively it just raises an instance
> of X which is constructed with an empty argument list. Therefore, "raise X()" is
> equivalent, as far as I know.

Not completely, although that may be considered an implementation detail.

When you raise an exception instance, it gets instantiated before being
raised (by your own code). So you control exactly how the exception
instance comes to life.

When you raise the class instead of the instance, it may or may not get
instantiated, depending on how it is being caught or discarded (and by
whom, e.g. internally in the interpreter). In most cases, it will be
instantiated, but only when someone catches it, i.e. at a later time, after
raising it. If the instantiation of the exception has side effects, or if
it fails for some reason (e.g. bad or missing arguments), the time of
instantiation may make a difference. It's obviously bad design to use side
effects here, but it's equally bad design to silently rely on it being side
effect free.

Note that if the exception happens to never get instantiated, you will safe
a tiny bit of time for the overall propagation. But since it's hard to tell
if that will happen or not, it would be a rather misguided micro
optimisation for most Python code to base your decision on this, at least
without prior benchmarking (with a real work-load etc.).

In general, I tend to raise exception types only for very safe and common
built-in exceptions, such as StopIteration, but whenever they take an
argument, I raise the instance instead. For user provided exceptions, there
is no real excuse for raising the type.

BTW, StopIteration takes an optional argument in Python 3.3, but that's not
a feature that is generally going to be used by Python code, I assume. So
I'll just keep raising the type. :)

Stefan




More information about the Python-list mailing list