raising classes

Tim Peters tim.one at comcast.net
Mon Aug 19 19:29:53 EDT 2002


[Aahz]
> The latter is what I would have guessed.  Which brings me to my real
> question:
>
> Obviously *something* must be instantiated on a per-exception basis.
> What kind of object is it?

Exceptions at the C level aren't the same thing as exceptions at the Python
level.  At the Python level, the object is either the string exception, or
an instance of the exception class.  Under the covers, Python doesn't bother
to build an instance of the exception class unless it's actually needed ==
shows up at the Python level.  What this *really* saves is all under the
covers too:  many times Python raises an exception internally, but the
caller sees that and decides it's not an exception it cares about, so clears
it.  In that case, no instance is ever created.

> There was a recent thread on python-dev that mentioned lazy instantiation
> of exceptions at the C level; does that apply to for loops?

It has only to do with whether an exception instance is needed <wink>.

> That is, with the following code, does an actual exception object get
> created?
>
>     def f():
>         yield 1
>         raise StopIteration
>
>     for i in f():
>         print i

Who knows?  Not me.  The exception-handling code is excruciating.  Let's
see:

C:\Code\python\PCbuild>python
Python 2.3a0 (#29, Aug 15 2002, 18:15:33) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def speak(self):
...     print "I was called!"
...
>>> StopIteration.__init__ = speak
>>>
>>> def f():
...     yield 1
...     raise StopIteration
...
>>> for i in f():
...     print i
...
1
I was called!
>>>

So, yes, under current CVS it does create an instance of StopIteration.  I
was mildly surprised that it also does here:

>>> list(f())
I was called!
[1]
>>>

It turns out that if you raise an exception at the Python level, an instance
is always created.  If we change f() so that Python raises StopIteration
internally, the story changes:

>>> def f():
...     yield 1
...
>>> list(f())
[1]
>>>

clear-as-mud-but-twice-as-fun-ly y'rs  - tim





More information about the Python-list mailing list