tags:

views:

273

answers:

6

I am an experienced developer new to python, and still catching myself writing correct but unpythonic code. I thought it might be enlightening and entertaining to see small examples of python code people have written that in some way clashes with the generally preffered way of doing things.

I'm interested in code you actually wrote rather than invented examples. Here is one of mine: In code that was expecting a sequence that could be empty or None I had

if data is not None and len(data) > 0:

I later reduced that to

if data:

The simpler version allows additional true values like True or 10, but that's ok because the caller made a mistake and will get an exception from the statements within the if.

A: 

I have been doing lots of python for years, and I prefer the more verbose first example to the more "pythonic" example.

Maybe it's not the party line, but it is much clearer in intent, and will make much more sense to other developers who may or may not know all the little secrets of python.

ymmv

The more verbose form is wildly unnecessary and actually evaluates slower since it requires more operators.
Soviut
in all but most tight loop, that is entirely irrelevant.
+3  A: 

Some unpythonic habits that one could inherit from C-like languages:

1) The unnecessary semicolon:

printf "Hello world";

2) Unnecessary indexes:

# Bad
for i in range(len(myList)):
    print myList[i]

# Good
for item in myList:
    print item
Federico Ramponi
+2  A: 

My bad habit was:

index = 0
for item in someCollection:
    doSomething(index, item)
    index += 1

Instead of:

for index, item in enumerate(someCollection):  
    doSomething(index, item)

Which is much cleaner :-)

Also - beware of simple

if someList:

This can hurt if someList will become positive integer, or non-empty string or whatever. The error can become hard to find, while

if len(someList):

Would catch such error immediately.

Abgan
+2  A: 

The most unpythonic code I write is to mistakingly reinvent something which already exists in the library or has been overhauled (such as the DSU idiom) - noticing this, ripping it all out, and replacing it with (what is usually) a one-liner feels good.

gridzbi
What IS the "the DSU idiom"?
mdorseif
Example of DSU and the changes made in 2.4: http://tinyurl.com/99gfpu (google books)
gridzbi
Google books told me that I can't view that page. See stray neuron for DSU description and example: http://www.strayneuron.com/blog/archives/298
Abgan
+6  A: 

I find manual type checking the most "unpythonic" (although bad in general too). There's two usual cases this is abused. The first is when the logic of the function differs based on the type of the argument. For instance:

def doStuff (myVar):
    if isinstance (myVar, str):
        # do stuff
        pass
    elif isinstance (myVar, int):
        # do other stuff
        pass

The second is when the programmer tries to make a strongly typed function like you would expect to find in a statically typed language.

def doStuff (myVar):
    if not isinstance (myVar, int):
        raise TypeError ('myVar must be of type int')
EvilRyry
A: 
import random
make_token = (lambda chars, length:"".join([chars[random.randint(0,len(chars)-1)] for c in range(0, length)]))
random_token = make_token("abcdefghijklmnopqrstuvwxyz0123456789", 20)

This made a random token of length 20 made up of the character set put in. I have since learned the error of my ways. ;)

Evan Fosmark
So what was the good solution? Was it: ''.join(random.choice(string.lowercase + string.digits) for _ in range(20))
Kiv