views:

168

answers:

5

Possible Duplicate:
Common Pitfalls in Python

I'm learning Python and I come from a diverse background of programming languages. In the last five years, I've written quite a bit of Java, C++, VB.Net, and PHP. As many of you might agree, once you learn one programming language, learning another is just a mater of learning the differences in syntax and best practices.

Coming down from PHP, I've become very accustomed to a lot of script-style language features. For instance, stuff like this tickles me insides:

# Retrieve the value from the cache; otherwise redownload.
if(!($value = $cache->get($key)))
    # Redownload the value and store in the cache.
    $cache->set($key, $value = redownload($key));

Python, though, doesn't consider assignment to be an expression. OTOH, it does support nice things like the in construct, which I find to be one of the greatest inventions of all time. x in y is so much nicer than !empty($y[$x]).

What other nuances, "missing" features, and performance bottlenecks should I watch out for? I'm hoping to make as seamless a transition into Python development as possible, and hope to learn some of the secrets that will help to smooth out development time and eliminate trial and error. Your insight is appreciated!

+2  A: 

Threads do not do what you think they do, and probably shouldn't be used how you're used to using them. This is a huge gotcha for many people, especially for those used to Java where the custom is to subclass Thread implement the Runnable interface to do asynchronous work, and where there is language support for running threads in parallel (on machines with multiple CPU cores).

In general you probably don't want threads at all, but subprocesses. See my answer to the question "python threading and performace?".

(In more general, there might be a better way altogether.)

detly
"especially for those used to Java where the custom is to subclass Thread to do asynchronous work" - Seriously? Who would do such a thing??
perp
I realise now I should have said, "implement Runnable." Sorry, I haven't used Java in years. I'm perfectly happy to be corrected if I'm still wrong.
detly
A: 

Exceptions are your friend.

In contrast with languages like C and PHP which use the return value to indicate errors, Python uses exceptions to interrupt the program instead of allowing the errors to cause further problems down the line.

Ignacio Vazquez-Abrams
+3  A: 

For your example, the usual way would be something like this

try:
    value = cache[key]
except KeyError:
    value = cache[key] = redownload(key)
gnibbler
...or use a `defaultdict` with `redownload` as the factory function.
detly
@detly, the factory function for defaultdict is called without arguments
gnibbler
+2  A: 

This one took me a few hours to figure out when I first encountered it in a real program:

A default argument to a function is a mutable, static value.

def foo(bar = []):
  bar.append(1)
  print(bar)

foo()
foo()

This will print

[1]
[1, 1]
Thomas
Wow, ok. That's pretty unexpected.
mattbasta
A: 

Pythonic code is usually much faster than C-like code.

Something like:

new_list=[]
for i in xrange(len(old_list)):
   new_list.append(some_function(old_list[i]))

is better written as:

new_list=[some_function(x) for x in old_list]

or

new_list=map(some_function,old_list)
MAK