Comparison function as class method: how?

Alex Martelli aleax at aleax.it
Thu May 8 11:37:52 EDT 2003


Jeff Stewart wrote:

> I was writing a small class yesterday that maintains a list of file
> statistics.  I want this class to have a sortByModTime() method, but I
> couldn't get Python to accept a sort()-compatible comparison function as a
> class method.  It kept telling me that the function expected 'self' as the
> first argument.  I understand that all class methods have this
> requirement, but surely there's a way to encapsulate a comparison function
> in the class containing the data it sorts!
> 
> Is there a way to pull this off?

Using a clear terminology would help.  A class method is a special
construct that receives a CLASS, rather than an INSTANCE, as its
first argument (you can call it either on the class or on any of
its instances).  I very much doubt you want that.  Much more likely
you want a static method, which receives no automatic argument.  E.g.:

class Tracker(object):
    def __init__(self):
        self.modtime = time.time()
    def byModTime(a, b):
        return cmp(a.modtime, b.modtime)
    byModTime = staticmethod(byModTime)

Now, given a list L of instances of Tracker, you can, if you wish,
call L.sort(Tracker.byModTime).

Note that this will of course be *WAY* slower than the D-S-U
idiom, which you might also choose to encapsulate as a staticmethod:

    def sortByTime(listofinstances):
        auxlist = [(x.modtime, x) for x in listofinstances]
        auxlist.sort()
        listofinstances[:] = [x for mt, x in auxlist]
    sortByTime = staticmethod(sortByTime)

to be called as Tracker.sortByTime(L).  But, if you are in no hurry 
and have made a vow to never use D-S-U on Thursdays, the other
approach should also work and produce the same ordering.


Alex





More information about the Python-list mailing list