[Tutor] __cmp__() method examples?
Rob McGee
i812@iname.com
Wed, 5 Dec 2001 21:35:47 -0600
I haven't found many examples of how to do a Class.__cmp__() method. I
have a class whose instances have a certain alphabetic value which
should always be unique. I figured I would only be comparing these class
instances to other instances of the same class, so I chose to compare
based on that alphabetic value.
Maybe an example will clarify:
{code}
import random
class Project:
def __init__(self, name):
self.name = name
self.value = random.randrange(1, 100)
def __str__(self):
return self.name
def __cmp__(self, other):
if self.name < other.name: # compare name value (should be unique)
return -1
elif self.name > other.name:
return 1
else: return 0 # should mean it's the same instance
# now generate class instances -- this is always done automatically
from string import uppercase
for letter in uppercase:
execStr = letter + ' = Project("' + letter + '")'
# example -- 'A = Project("A")', 'Z = Project("Z")
exec(execStr)
{/code}
(Sorry about the exec's, but I really don't know another way to do what
I want. I want these instances in the global namespace, and I need to
know exactly what each one is named. At least I think I do. Suggestions
about other ways to approach this would be welcomed, too. :) Like with
no exec's, or with the instances in something other than globals(), how
would I be able to retrieve and alter their properties?)
The user interacts with these class instances through code like this:
{code}
def getProjectName():
text = raw_input('Project name: ')
text = text.upper()
return text
def objectEntry(text):
"""converts text to an object name"""
try:
object = eval(text)
return object
except: return
def ifInstance(object, className=Project):
"""returns object if it's an instance of className"""
try:
if object.__class__ == className:
return object
except: return
def myStupidMenu():
keepGoing = 1
while keepGoing:
prompt = 'stupid menu ("g/x"): '
choice = raw_input(prompt)
choice = choice.upper()
if choice == "G":
text = getProjectName()
if text:
object = objectEntry(text)
if object:
instance = ifInstance(object)
print instance, '=', instance.value
elif choice == "X":
keepGoing = 0
else:
print "\tyou're as stupid as this menu!"
myStupidMenu()
{/code}
I'm getting errors which indicate that the class instances are being
compared with other objects (AttributeError: object has no "name"
attribute.) I don't know if the sample code here will generate those
errors -- probably not -- but what I'm hoping for is just a little
guidance on how to properly implement a __cmp__() method.
What I think I'll try -- the idea came to me while writing this :) -- is
to put code in Project.__cmp__() like the ifInstance() above. If "other"
isn't an instance of self.__class__, don't try to get other.name.
Oh, I should also mention that I got into an infinite loop with another
class.__cmp__() method. That class was more complicated, and I had
several if/elif loops to compare other attributes. The fourth and final
such loop simply compared "self" and "other". I believe that was where
the loop occurred, and it was in sorting a list of instances of that
class (I don't think there were any non-instance members of the list.)
By removing the self/other raw comparison I eliminated the infinite
loop. But that experience gives me the idea that I'm missing something
about how to do a Class.__cmp__().
Thanks again all,
Rob - /dev/rob0