John Machin wrote:
> Simon Forman wrote:
>
> >
> > |>> class f:
> > ...     def __init__(self):
> > ...             del self
>
> Of course nothing happens. Args are local variables. 'self' is is a
> vanilla arg of a vanilla function.

I know.

> > ...
> > |>> e = f()
> > |>> e
> > <__main__.f instance at 0xb7dd91ec>
> >
> >
> > |>> class f:
> > ...     def __init__(self):
> > ...             return None
>
> Of course nothing different happens. There is always an implicit
> "return None" when control falls off the end of a function. Making it
> explicit changes nothing.

I know

> > ...
> > |>> e = f()
> > |>> e
> > <__main__.f instance at 0xb7dd934c>
>
> The whole idea of "del self" or "return None" is not a goer. "self" is
> a reference to the (mutable) newly created object. After __init__ has
> finished mutating it, the constructor will return the object to the
> constructor's caller.

I know that too.

> The whole idea that None should be returned in the event of error is
> ... well, let's just say it leaves me speechless.

Tell me about it.

> > But you could raise an exception and check for it:
> >
> > |>> class f:
> > ...     def __init__(self, flag=True):
> > ...             if not flag:
> > ...                     raise
>
> Please read the manual. A lone "raise" does *not* raise an anonymous
> exception; it re-raises an exception that has just been trapped. If
> there are none, it raises None, which causes (as documented) a
> TypeError.

I know

> > ...
> > |>> def f_factory(flag):
> > ...     try:
> > ...             e = f(flag)
> > ...     except:
>
> Blanket exception catching is *never* a good idea. In this case the
> exception being caught is an artifact of your use of the unadorned
> "raise".

I know

> If you inserted here:
> ...         import sys
> ...         x, y = sys.exc_info()[:2]
> ...         print x, y
> you would get:
> exceptions.TypeError exceptions must be classes, instances, or strings
> (deprecated), not NoneType

Yep.

> > ...             e = None
> > ...     return e
> > ...
> > |>> foo = f_factory(True)
> > |>> foo
> > <__main__.f instance at 0xb7dd944c>
> > |>> foo = f_factory(False)
> > |>> foo
> > |>> print foo
> > None
>
> HTH,
> John

The entire post was meant as a pedantic exercise illustrating what not
to do (and how easy it is to figure that out with an interactive
session,) and sketching how to raise and check for an error instead.

In the three seconds I spent thinking about it, I couldn't decide what
exception to raise, so I used the wicked bare raise and except.  I'm
certainly not advocating their use, but perhaps I should've made that
plain in a post intended to be "educational".

In any event, with your comments it's out there now, and the
educational value of this entire thread has been improved.  Thanks
John.

Peace,
~Simon

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to