Method Underscores? (and a 'solution')

Jeremy Bowers jerf at jerf.org
Thu Oct 21 15:10:41 EDT 2004


On Thu, 21 Oct 2004 05:57:25 +0000, Chris S. wrote:

> Is there a purpose for using trailing and leading double underscores for
> built-in method names? ... a key arguing point against Python.

Yes, I've noticed this one come up a lot on Slashdot lately, more so than
whitespace issues. I haven't checked to see if it's all one guy posting it
or not; next time I think I will, it seems suspiciously sudden to me.

As an argument against Python, implicitly in favor of some other language,
it boggles my mind. Whitespace complaints made before even trying Python I
can at least make some sense of; there are enough people unwilling to even
try something different unless your new language is an exact clone of the
one they already know that you'll hear from them. (Note: This is as
opposed to the small-but-real group of people who actually *try* it and
don't like it; those people I can respect, even as I disagree with them.) 

But what mystical language exists that uses less punctuation than Python?
I've tried to come up with it, and even the obscure ones I can come up
with use more. (The closest one to Python I know is one called UserTalk,
in Frontier, but that one looses due to its use of addresses and
dereferencing, which adds enough punctuation to be harder to read. Also,
it doesn't *have* classes, so no method wierdness.) 

Complaining about them in the sense of "I think we could improve Python if
we drop the underscores" makes sense; again, I'm not talking about that
sense, nor am I trying to make that argument. But as some sort of reason
to not use Python? Riiiiiiiiiight... you might as well just come out and
admit you don't *want* to try it. There's nothing wrong with that, you
know.

Also, since I'm sick of hearing about this, and I intend to use a link to
this post via Google News as a standin for repeating this argument again
somewhere else, here is a metaclass that will make the "ugly underscores"
go away. But look at that list in the variable "MagicMethods"... are you
really sure you're willing to give all of those up? Of course, you can
selectively use the metaclass, but then you have inconsistancy in your
program. But whatever...

Also note the list of methods dwarfs the actual code it took to do this.

-------------------------

"""I'm sick of hearing people bitch about the underscores. Here, let
me 'fix' that for you.

You may need to add magic method names to the set if you implement
other protocol-based things, like in Zope. I did add the Pickle
protocol in because I know where to find it.

Set your class's metaclass to UnUnderscore, and name your methods
'cmp' or 'nonzero' instead of '__cmp__' or '__nonzero__'; see the
example in the sample code."""

import sets

__all__ = ['UnUnderscore']

MagicMethods = sets.Set(('init', 'del', 'repr', 'str', 'lt', 'le',
                         'eq', 'ne', 'gt', 'ge', 'cmp', 'rcmp',
                         'hash', 'nonzero', 'unicode', 'getattr',
                         'setattr', 'delattr', 'getattribute', 'get',
                         'set', 'delete', 'call', 'len', 'getitem',
                         'setitem', 'delitem', 'iter', 'contains',
                         'add', 'sub', 'mul', 'divmod', 'pow',
                         'lshift', 'rshift', 'and', 'xor', 'or',
                         'div', 'truediv', 'radd', 'rsub', 'rmul',
                         'rdiv', 'rtruediv', 'rmod', 'rdivmod',
                         'rpow', 'rlshift', 'rrshift', 'rand', 'rxor',
                         'ror', 'iadd', 'isub', 'imul', 'idiv',
                         'itruediv', 'ifloordiv', 'imod', 'ipow',
                         'ilshift', 'irshift', 'iand', 'ixor', 'ior',
                         'neg', 'pos', 'abs', 'invert', 'complex',
                         'int', 'long', 'float', 'oct', 'hex',
                         'coerce',

                         # Pickle
                         'getinitargs', 'getnewargs', 'getstate',
                         'setstate', 'reduce', 'basicnew')) 

class UnUnderscore(type):
    """See module docstring."""
    def __init__(cls, name, bases, dict):
        super(UnUnderscore, cls).__init__(name, bases, dict)
        for method in MagicMethods:
            if hasattr(cls, method):
                setattr(cls, "__" + method + "__",
                        getattr(cls, method))
                delattr(cls, method)

if __name__ == "__main__":
    # simple test
    class Test(object):
        __metaclass__ = UnUnderscore
        def init(self):
            self.two = 2
        def len(self):
            return 3
    t = Test()
    if len(t) == 3 and t.two == 2:
        print "Works, at least a little."
    else:
        print "Not working at all."




More information about the Python-list mailing list