Is this an Intended behaviour of __getattr__?

Volucris volucris at hotmail.com
Fri Jul 27 05:47:35 EDT 2001


Yeah, I didn't even notice that before. You know what else I didn't notice
before? That the 3rd and 4th elements are f.next.next. I think I was too
busy looking at the logic of the method to notice the simplicity of the
question.

There must be some kind of Exception suppression, because look at this code:

---Begin Code---
#an Exception of my own ingenious design
class MyError(Exception):
  def __init__(self):
    print "I have been called!"

class Node:
    def __init__(self):
        self._next=None
    def __getattr__(self,attr):
        if attr=='next':
            if self._next is not None:
                return self._next
            else:
                self._next=Node()
                return self._next
        print attr,"was called..."
        #got rid of your 'normal' Exception raising, and raised my own
        raise MyError
---End Code---

And look at the output I get:

  __str__ was called...
I have been called!
__repr__ was called...
I have been called!
<__main__.Node instance at 00F818DC>
 __str__ was called...
I have been called!
__repr__ was called...
I have been called!
<__main__.Node instance at 00F818DC>
 __str__ was called...
I have been called!
__repr__ was called...
I have been called!
<__main__.Node instance at 00F810AC>
 __str__ was called...
I have been called!
__repr__ was called...
I have been called!
<__main__.Node instance at 00F810AC>
errorPlz was called...
I have been called!


So, the exception _is_ being raised, but it's not being displayed. Hmmmm. I
have no idea.  Where are those PythoGeniuses? <Whistles>
--

Volucris (a) hotmail.com
"Eu não falo uma única palavra do português."

"Grace" <nospam at nospam.com> wrote in message
news:OR887.104175$ph7.16309267 at news.hananet.net...
> "Volucris" <volucris at hotmail.com> wrote in message
> news:3b6111de$0$325$6e49188b at news.goldengate.net...
> >
> > "Grace" <nospam at nospam.com> wrote in message
> > news:uu787.103805$ph7.16107665 at news.hananet.net...
> > > I'm a bit confused with this:
> > >
> > > class Node:
> > >     def __init__(self):
> > >         self._next=None
> > >     def __getattr__(self,attr):
> > >         if attr=='next':
> > >             if self._next is not None:
> > >                 return self._next
> > >             else:
> > >                 self._next=Node()
> > >                 return self._next
> > >         print attr,"was called..."
> > >         error=3/0  #supposed to raise exception
> > >         raise AttributeError
> > >
> > > if __name__=='__main__':
> > >     f=Node()
> > >     links=[f.next,f.next,f.next.next,f.next.next]
> > >     for each in links:
> > >         print each
> > >     print f.errorPlz
> > >
> > > And this yields exactly,
> > >
> > >  __str__ was called...
> > > __repr__ was called...
> > > <__main__.Node instance at 0081608C>
> > >  __str__ was called...
> > > __repr__ was called...
> > > <__main__.Node instance at 0081608C>
> > >  __str__ was called...
> > > __repr__ was called...
> > > <__main__.Node instance at 0081601C>
> > >  __str__ was called...
> > > __repr__ was called...
> > > <__main__.Node instance at 0081601C>
> > > al was called...
> > > Traceback (most recent call last):
> > >   File "...", line 22, in ?
> > >     print f.al
> > >   File "...", line 12, in __getattr__
> > >     k=3/0
> > > ZeroDivisionError: integer division or modulo by zero
> > >
> > > Why did it suck up all ZeroDivisionErrors while outputting the "was
> > > called..." messages? Special case with magic methods? Is this an
> intended
> > > behaviour? Then what is the exact process/mechanism?
> > >
> > > Thanks in advance.
> > >
> > >
> >
> > in __getattr__ if the attr is 'next', if checks the value of _next and
> > returns whether it's None or not. the code after return never gets
> executed.
> > the only time it didn't return first, was when __getattr__ was called
> with
> > 'errorPlz' (not 'next').
> >
> > That was too wordy, but I hope it's intelligible.
> > --
>
> Thanks, but I don't think it answers my question.
>
> I think when __repr__ and __str__ are called internally via the
interpreter
> as in the print statement, it passes through the __getattr__ method of
Node
> class while all exceptions are simply ignored.
>
> Am I right on this? Not sure.
>
> ps. when  I use "not equal operator" != in the "if self._next is not
None:"
> line, __ne__ (above python 2.0) is searched after, and as it fails,
> __getattr__ is called, and goes into the same strange process as above,
> ignoring all exceptions.
>
>
>





More information about the Python-list mailing list