newbie class-building question

J

jrpfinch

I am constructing a simple class to make sure I understand how classes
work in Python (see below this paragraph).

It works as expected, except the __add__ redefinition. I get the
following in the Python interpreter:
Traceback (most recent call last):

Please could you let me know where I am going wrong. I have hacked
around with the code and tried googling this error message but am
having difficulty finding the source of the problem.

Many thanks

Jon

class myList:
def __init__ (self,value=[]):
self.wrapped=[]
for x in value :
self.wrapped.append(x)
def __repr__ (self):
return `self.wrapped`
def __getattr__ (self,attrib):
return getattr(self.wrapped,attrib,'attribute not found')
def __len__ (self):
return len(self.wrapped)
def __getitem__ (self,k):
return self.wrapped[k]
def __add__(self,other):
return self.wrapped+other

class myListSub(myList):
classCounter=0
def __init__ (self,value=[]):
self.instanceCounter=0
myList.__init__(self,value)
def __add__(self,other):
myListSub.classCounter=myListSub.classCounter+1
self.instanceCounter=self.instanceCounter+1
myList.__add__(self,other)
def getCounters (self):
return "classCounter=%s instanceCounter=%s" %
(myListSub.classCounter,self.classCounter)
 
P

Peter Otten

jrpfinch said:
I am constructing a simple class to make sure I understand how classes
work in Python (see below this paragraph).

It works as expected, except the __add__ redefinition. I get the
following in the Python interpreter:
a=myListSub()
a []
a+[5]
Traceback (most recent call last):

Please could you let me know where I am going wrong. I have hacked
around with the code and tried googling this error message but am
having difficulty finding the source of the problem.

class myList:
def __init__ (self,value=[]):
self.wrapped=[]
for x in value :
self.wrapped.append(x)
def __repr__ (self):
return `self.wrapped`
def __getattr__ (self,attrib):
return getattr(self.wrapped,attrib,'attribute not found')

When Python is looking for an attribute that neither exists in myList nor
the 'wrapped' list, you give back a string.
In your case this happens for the __coerce__() method, and the interpreter
ends up calling "attribute not found" which of course must fail. The
solution:

- Don't provide a bogus default for getattr(), and get a traceback that is
easier to understand.
- Use new-style classes (i.e. class myList(object): ...) which look for
special methods in the class, not the instance.


Peter
 
J

Jon Clements

jrpfinch said:
I am constructing a simple class to make sure I understand how classes
work in Python (see below this paragraph).

It works as expected, except the __add__ redefinition. I get the
following in the Python interpreter:
a=myListSub()
a []
a+[5]
Traceback (most recent call last):

Please could you let me know where I am going wrong. I have hacked
around with the code and tried googling this error message but am
having difficulty finding the source of the problem.

Many thanks

Jon

class myList:
def __init__ (self,value=[]):
self.wrapped=[]
for x in value :
self.wrapped.append(x)
def __repr__ (self):
return `self.wrapped`
def __getattr__ (self,attrib):
return getattr(self.wrapped,attrib,'attribute not found')
def __len__ (self):
return len(self.wrapped)
def __getitem__ (self,k):
return self.wrapped[k]
def __add__(self,other):
return self.wrapped+other

class myListSub(myList):
classCounter=0
def __init__ (self,value=[]):
self.instanceCounter=0
myList.__init__(self,value)
def __add__(self,other):
myListSub.classCounter=myListSub.classCounter+1
self.instanceCounter=self.instanceCounter+1
myList.__add__(self,other)
def getCounters (self):
return "classCounter=%s instanceCounter=%s" %
(myListSub.classCounter,self.classCounter)

I'm not sure what you're trying to achieve with the __getattr__ in
myList, but the reason your __add__ isn't working is that when "a +
[5]" is executed, Python tries to find a __coerce__ attribute (to prove
this just put a "print attrib" as the first line of your __getattr__).
Your customer __getattr__ returns a default string object of 'attribute
not found', when it fails to locate this. Python then attempts to call
this string, and as your exception states -- strings aren't callable.

That should give you enough information to be going onwith.

Also, if you're trying to get use to classes, I would suggest you start
off with the 'new-style' classes; those are the ones that derive from
object. A quick google for new-style classes will sort you.

hth a bit,

Jon.
 
J

jrpfinch

Thank you this is very helpful. The only thing I now don't understand
is why it is calling __coerce__. self.wrapped and other are both
lists.

Thanks

Jon
 
J

Jon Clements

jrpfinch said:
Thank you this is very helpful. The only thing I now don't understand
is why it is calling __coerce__. self.wrapped and other are both
lists.

Yes, but in "a + [5]", *a* is a myListSub object -- it's not a list! So
__coerce__ is called to try and get a common type...

Try this in myList...

# We could check the type of 'other' to determine what we return
here....
# At the moment, we return a list, whose + operator, requires another
list so this works
# and gives an exception if it's not for us
def __coerce__(self,other):
return self.wrapped, other

#
def __add__(self,other):
return self + other



hth

Jon.
 
G

Gabriel Genellina

I am constructing a simple class to make sure I understand how classes
work in Python (see below this paragraph).

It works as expected, except the __add__ redefinition. I get the
following in the Python interpreter:
a=myListSub()
a []
a+[5]
Traceback (most recent call last):

def __getattr__ (self,attrib):
return getattr(self.wrapped,attrib,'attribute not found')

This is the culprit; should raise AttributeError when not found, not
return a string.
Just return getattr(self.wrapped, attrib) and let the error propagate.


--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top