Raising objects
Steven Taschuk
staschuk at telusplanet.net
Wed Apr 30 12:27:34 EDT 2003
Quoth Alex Martelli:
> Steven Taschuk wrote:
[inability to raise new-style objects]
> > I don't have a real use case either, but it does seem rather
> > arbitrary. Is there an implementation reason for this restriction?
>
> In a sense, yes: there is no way to check if something "is a new-style
> class" as opposed to "any type whatsoever" -- so one could end up
> raising lists, tuples, strings (shades of the past...), whatever.
How about this?
>>> def newstyle(obj):
... """Whether obj is an instance of a new-style class."""
... return hasattr(obj, '__class__') \
... and issubclass(obj.__class__, object)
...
>>> class OldStyle: pass
...
>>> class NewStyle(object): pass
...
>>> newstyle(OldStyle())
0
>>> newstyle(NewStyle())
1
>>> newstyle(Exception())
0
This function can even be used directly on the classes:
>>> newstyle(OldStyle)
0
>>> newstyle(NewStyle)
1
>>> newstyle(Exception)
0
(Since the type 'type' is new-style but the type 'class' is not.)
It would produce counterintuitive results in such use if it were
possible for a new-style class object to be an instance of an
old-style class... is that possible?
This function does report that strings and lists are new-style.
Aren't they?
> What I hope to see happen eventually is a spec that raise can use:
>
> -- any subclass of Exception (by that time a new-style class), OR
> -- for backwards compatibility any old-style class, OR
> -- for VERY backwards compatibility, any string
>
> [and also INSTANCES as well as classes for the first two cases].
That seems reasonable.
But is there a problem with being able to raise anything? Perhaps
some class of easy-to-produce bugs that I'm not seeing?
What I'm imagining at the moment is this: suppose you can raise
anything, and except clauses identify the exceptions to be caught
by their class. The only problem I can see with this is that it
clashes with the present (backwards-compatible) treatment of
raised strings:
try:
raise 'foo'
except 'foo':
print 'wah'
wouldn't print 'wah', since 'foo' is not an instance of 'foo'.
You'd have to do something like
try:
raise 'foo'
except str, e:
if e == 'foo':
print 'wah'
else:
raise
which is ugly.
So, suppose that strings were special-cased for backwards
compatibility:
def exceptmatch(exception, classtomatch):
"""Whether an except clause specifying classtomatch should
catch exception.
"""
if isinstance(classtomatch, str):
return exception == classtomatch
else:
return isinstance(exception, classtomatch)
(I ignore for simplicity except clauses which match more than one
class.)
Is there a problem with this scheme?
> Exactly: even in my hoped-for new spec, you'd have to wrap this
> in a subclass of Exception. Facilitating the [ab]use of the
> exception mechanism for generalized control flow is, I suspect,
> NOT on the list of priorities in the BDFL's mind;-). Feel free
> to open a PEP to settle that beyond any doubt, though...;-)
Heh. I imagine you're right. I'd argue in favour of a scheme
such as above chiefly on the basis of regularity (rather than for
making my silly example work).
I just don't see a good reason not to be able to raise new-style
objects, so to me it's an arbitrary restriction and as such makes
the language slightly uglier. (It is, of course, a very minor
issue; I hadn't even noticed that Exception is old-style until
this thread.)
--
Steven Taschuk staschuk at telusplanet.net
"[T]rue greatness is when your name is like ampere, watt, and fourier
-- when it's spelled with a lower case letter." -- R.W. Hamming
More information about the Python-list
mailing list