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