Minority Opinions

Not everyone can be mainstream, after all.

Five things to hate about Python

leave a comment »

Now, to balance out my previous post, and as a little meme following, I present my list of grievances with, arguably, the best language ever.

if __name__ == "__main__":

Yes, it can be helpful to make a file usable as both a script and as an importable module, but this particular spelling doesn’t convey the real point very well.  On top of that, it has caused problems with pickling, relative imports, and double imports.  It really should have been changed years ago, but never could because it’s used in perhaps a quarter of all Python files in existence.

The actual problem areas are being hacked around with even more dunder module attributes in recent and upcoming versions, but the ugliness persists. Surely we could have come up with something better by now? Perhaps “if __main__:“?

for key in dictionary:

Yes, iterating over a dictionary maintains a “for key in container: assert key in container” invariant, but it still feels inefficient. I almost always want the value with the key, which means I have two options:

  • for key in dictionary: process(key, dictionary[key])
    This seems to be the preferred method, but involves extra dictionary accesses that don’t seem to be necessary. It’s particularly annoying when the loop body uses the value more than once; should I be spending an extra line to copy the value into a new name?
  • for key, value in dictionary.iteritems(): process(key, value)
    This involves an attribute that isn’t guaranteed to be available on all dict-like containers, and that changes its name in Python 3. It’s a little uglier on the for line than it really needs to be. However, it seems to be more efficient than the canonical method, and it makes the loop body cleaner.

This is a clear violation of the Zen of Python. Unfortunately, it doesn’t seem likely to change ever, much less any time soon.

while var := value():

Why, oh why, can’t we have an assignment operator that works in control structures? I can understand the prohibition of the single equal sign in conditions (it prevents an easily overlooked error), but colon-equal has just as much history as an assignment operator, and would be easy to understand.

Okay, so the while loop isn’t the best example, because it could, with some work, be transformed into a for loop instead. The very best example is elif:

if condition:
    do(something)
elif result := process():
    handle(result)
else:
    report(problem)

Without the mid-condition assignment operator, the second block needs to expand to ugliness levels:

if condition:
    do(something)
else:
    result = process()
    if result:
        handle(result)
    else:
        report(problem)

And that’s just with one extra level; I’ve seen more. So which is more important: “There should be only one obvious way to do it,” or “Flat is better than nested”?

break 2

If you’re in a pair of nested loops, and you want to break out of the outer loop, what do you do? Refactor the loops into a new function?

def newfunc(outer, inner):
    iterations = 0
    for foo in outer:
        for bar in inner:
            iterations += 1
            if foo + bar == "BY":
                return
iterations = newfunc("ABCD", "XYZ")

Alternatively, do you raise an exception?

iterations = 0
try:
    for foo in "ABCD":
        for bar in "XYZ":
            iterations += 1
            if foo + bar == "BY":
                raise StopIteration
except StopIteration:
    pass

Why can’t we instead give break an optional argument, like PHP does, specifying the number of loops to break through?

python setup.py build

Python packaging is messy. PyPI, easy_install, and virtualenv have made it a whole lot easier to install pre-built packages with their dependencies, but not all that much to package your own work. The distribute fork has made things even more confusing for now, but I’m hoping it will settle down into a convenient standard.

Meanwhile, Windows users occasionally ask me for the type of simple installer they’re used to, and I can’t seem to create one. Part of that’s probably my lack of access to a Windows machine, but what can I do to make it easier for a third-party packager?

Advertisements

Written by eswald

23 Mar 2011 at 10:46 am

Posted in Python

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s