471,319 Members | 1,600 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,319 software developers and data experts.

why __repr__ affected after __getattr__ overloaded?

Now I have to design a class that overload __getattr__, but after
that, I found the __repr__ have been affected. This is a simple
example model:
#!/usr/bin/env python

class test:
def __init__(self):
self.x = 1
def __getattr__(self, attr_name):
try:
return self.__dict__[attr_name]
except KeyError:
self.__dict__[attr_name] = 'inexistent'
return self.__dict__[attr_name]

t = test()
print t.x
print t.y
print type(t)
T = t
print T.x
print t

So far, I want the operation "print t" still return "<test instance
at ...>", but the reuslt is:
sh$ python test.py
1
inexistent
<type 'instance'>
1
Traceback (most recent call last):
File "testtree.py", line 23, in ?
print t
TypeError: 'str' object is not callable

I also tried to overload __repr__ itself:

#!/usr/bin/env python

class test:
def __init__(self):
self.x = 1
def __getattr__(self, attr_name):
try:
return self.__dict__[attr_name]
except KeyError:
self.__dict__[attr_name] = 'inexistent'
return self.__dict__[attr_name]
def __repr__(self):
return 'test.__repr__'

t = test()
print t.x
print t.y
print type(t)
T = t
print T.x
print t

But the result remains:
Traceback (most recent call last):
File "testtree.py", line 23, in ?
print t
TypeError: 'str' object is not callable

So why? What is the principles?

Jun 22 '07 #1
7 2235
En Fri, 22 Jun 2007 00:30:43 -0300, Roc Zhou <ch*******@gmail.com>
escribió:
Now I have to design a class that overload __getattr__, but after
that, I found the __repr__ have been affected. This is a simple
example model:
You are creating many attributes with value "inexistent", even special
methods. Put a print statement and see what happens:
#!/usr/bin/env python

class test:
def __init__(self):
self.x = 1
def __getattr__(self, attr_name):
try:
return self.__dict__[attr_name]
except KeyError:
print "Now creating:",attr_name
self.__dict__[attr_name] = 'inexistent'
return self.__dict__[attr_name]
--
Gabriel Genellina

Jun 22 '07 #2
I know what's wrong. Thank you. And I think
try:
return self.__dict__[attr_name]
is unnecessary, because python will do it itself for us.

So now I have to overload __str__, but how can I make self.__str__
print as builtin str(): at here, I want get the result like:
<test instance at 0xb7bbb90c>
?

On 6 22 , 12 55 , "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Fri, 22 Jun 2007 00:30:43 -0300, Roc Zhou <chowro...@gmail.com>
escribió:
Now I have to design a class that overload __getattr__, but after
that, I found the __repr__ have been affected. This is a simple
example model:

You are creating many attributes with value "inexistent", even special
methods. Put a print statement and see what happens:
#!/usr/bin/env python
class test:
def __init__(self):
self.x = 1
def __getattr__(self, attr_name):
try:
return self.__dict__[attr_name]
except KeyError:

print "Now creating:",attr_name
self.__dict__[attr_name] = 'inexistent'
return self.__dict__[attr_name]

--
Gabriel Genellina

Jun 22 '07 #3
return hex(id(self))

On 6 22 , 1 48 , Roc Zhou <chowro...@gmail.comwrote:
I know what's wrong. Thank you. And I think
try:
return self.__dict__[attr_name]
is unnecessary, because python will do it itself for us.

So now I have to overload __str__, but how can I make self.__str__
print as builtin str(): at here, I want get the result like:
<test instance at 0xb7bbb90c>
?

On 6 22 , 12 55 , "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Fri, 22 Jun 2007 00:30:43 -0300, Roc Zhou <chowro...@gmail.com>
escribió:
Now I have to design a class that overload __getattr__, but after
that, I found the __repr__ have been affected. This is a simple
example model:
You are creating many attributes with value "inexistent", even special
methods. Put a print statement and see what happens:
#!/usr/bin/env python
class test:
def __init__(self):
self.x = 1
def __getattr__(self, attr_name):
try:
return self.__dict__[attr_name]
except KeyError:
print "Now creating:",attr_name
self.__dict__[attr_name] = 'inexistent'
return self.__dict__[attr_name]
--
Gabriel Genellina

Jun 22 '07 #4
I'm sorry but I still have a question, look at this example:
>>class test:
.... def __init__(self):
.... self.x = 1
.... def __getattr__(self, attr_name):
.... print attr_name
.... if attr_name == 'y':
.... return 2
.... else:
.... raise AttributeError, attr_name
....
>>t = test()
t.x
1
>>t.y
y
2
>>print t.x
1
>>print t
__str__
__repr__
<__main__.test instance at 0xb7f6d6cc>

Since __str__ and __repr__ does not exist because their names was
printed, why not the "AttributeError" be raised?
Jun 22 '07 #5
En Fri, 22 Jun 2007 02:48:50 -0300, Roc Zhou <ch*******@gmail.com>
escribió:
I know what's wrong. Thank you. And I think
try:
return self.__dict__[attr_name]
is unnecessary, because python will do it itself for us.
Exactly; by the time __getattr__ is called, you already know attr_name is
not there.
So now I have to overload __str__, but how can I make self.__str__
print as builtin str(): at here, I want get the result like:
<test instance at 0xb7bbb90c>
?
I would do the opposite: *only* create inexistent attributes when they are
not "special". This way you don't mess with Python internals.

.... def __getattr__(self, name):
.... if name[:2]!='__' or name[-2:]!='__':
.... self.__dict__[name] = 'inexistent'
.... return self.__dict__[name]
.... raise AttributeError,name

This way you don't create "fake" attributes for things like __bases__ by
example, and dir(), vars(), repr() etc. work as expected.

--
Gabriel Genellina

Jun 22 '07 #6
En Fri, 22 Jun 2007 03:43:26 -0300, Roc Zhou <ch*******@gmail.com>
escribió:
I'm sorry but I still have a question, look at this example:
>>>class test:
... def __init__(self):
... self.x = 1
... def __getattr__(self, attr_name):
... print attr_name
... if attr_name == 'y':
... return 2
... else:
... raise AttributeError, attr_name
...
>>>t = test()
t.x
1
>>>t.y
y
2
>>>print t.x
1
>>>print t
__str__
__repr__
<__main__.test instance at 0xb7f6d6cc>

Since __str__ and __repr__ does not exist because their names was
printed, why not the "AttributeError" be raised?
This is the implementation of str() in action; tries to find a __str__
method and fails; tries to find a __repr__ instead and fails; then uses
the default representation.
See <http://docs.python.org/ref/customization.html#l2h-179>

--
Gabriel Genellina

Jun 22 '07 #7
Roc Zhou wrote:
I'm sorry but I still have a question, look at this example:
>>>class test:
... def __init__(self):
... self.x = 1
... def __getattr__(self, attr_name):
... print attr_name
... if attr_name == 'y':
... return 2
... else:
... raise AttributeError, attr_name
...
>>>t = test()
t.x
1
>>>t.y
y
2
>>>print t.x
1
>>>print t
__str__
__repr__
<__main__.test instance at 0xb7f6d6cc>

Since __str__ and __repr__ does not exist because their names was
printed, why not the "AttributeError" be raised?
Because classic classes invoke

t.__getattr__(self, "__repr__")

and expect that to return a proper __repr__() method -- unless __getattr__()
raises an AttributeError:
>>class Test:
.... def __getattr__(self, name):
.... if name == "__repr__":
.... raise AttributeError
.... return "<inexistent %r>" % name
....
>>t = Test()
t
<__main__.Test instance at 0x401d42ac>

If you use newstyle classes you won't run into that particular problem:
>>class Test(object):
.... def __getattr__(self, name):
.... return "<inexistent %r>" % name
....
>>t = Test()
t
<__main__.Test object at 0x401d426c>
>>t.yadda
"<inexistent 'yadda'>"

Jun 22 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Greg Brunet | last post: by
15 posts views Thread by Jim Newton | last post: by
7 posts views Thread by Ben Finney | last post: by
13 posts views Thread by Pelmen | last post: by
6 posts views Thread by Erik Johnson | last post: by
reply views Thread by Roc Zhou | last post: by
reply views Thread by Roc Zhou | last post: by
4 posts views Thread by Enrico | last post: by
7 posts views Thread by =?UTF-8?Q?Alexandru_Mo=C8=99oi?= | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.