total idiot question: +=, .=, etc...

Neel Krishnaswami neelk at brick.cswv.com
Fri Jun 25 04:09:19 CEST 1999


In article <slrn7f68br.2bp.thantos at brimstone.mecha>,
Alexander Williams <thantos at gw.total-web.net> wrote:
>On 23 Jun 1999 20:56:41 -0500, Neel Krishnaswami <neelk at brick.cswv.com> wrote:
>>It's just that writing self.__class__ is so *ugly*! Everything else
>>in Python is beautiful, too, which makes this stand out even more. 
>
>Er, that could be because you're doing it wrong?  Try:
>
>class Foo:
>    def __init__(me):
>        me.x = 9
>
>    def setX(me, val):
>        me.x = val

IMO, it's bad style to set properties that should belong to the type
in the instance initializer -- for example, the sort order is
something that's a property of the class, rather than the instances.

Here's an example from some code of mine (it's from a programmatic
front-end to Dejanews):

class Article:
    [...]
    #
    # To set the sort order, set Article.sortorder to one of the
    # keys of Article.comparators.
    #
    comparators = {'date':      lambda x,y: cmp(x.date,y.date),
                   'score':     lambda x,y: cmp(x.score,y.score),
                   'author':    lambda x,y: cmp(x.author,y.author),
                   'subject':   lambda x,y: cmp(x.subject,y.subject),
                   'newsgroup': lambda x,y: cmp(x.newsgroup,y.newsgroup)
                   }
    sortorder = 'date' # can be anything in Article.comparators.keys()

    [...]

    def __cmp__(self, other):
        return self.__class__.comparators[self.__class__.sortorder](self,
                                                                    other)

I want the user to be able to determine how a list of Article's can be
sorted by setting the class's sortorder member. So a statement like

>>> Article.sortorder = 'author'

would change how lists of articles are sorted. This is definitely 
something that's shouldn't be an instance attribute, imo; it would
defeat the purpose if each article could compare differently than
any other. (Oppose standardized testing! :])

But look how ugly that __cmp__ method is; it would be a lot clearer to
write something like

    def __cmp__(self, other):
        return Article.comparators[Article.sortorder](self, other)

because that would make it clearer what class state is being used, and
why. However, though it would be clearer to the programmer, it would
profoundly mess up inheritance.

It's perfectly reasonable for someone else to subclass Article and
override the Article.comparators attribute. (Say to add an ordering to
put Tim Peter's posts at the top of the list, or to use something
faster than my lambdas.) With the clear way of writing it, the
NewArticle class would mysteriously fail to do the right thing,
because the __cmp__ method would look in the Article class dictionary
without bothering to check NewArticle's.

This is an unusual glitch in Python; usually the readable way of doing
something is the right way of doing it. 

Maybe we could re-use the class keyword and let people write class.foo
inside class definitions, by analogy to writing self.foo to refer to
the current instance? And the class.foo syntax would get translated to
the equivalent of self.__class__? 

Hmm. Might hairify the grammar a bit too much, though. 


Neel




More information about the Python-list mailing list