June 06, 2008 at 11:42 Tags Python

Introduction

Update: A few words on my programming background. I'm most proficient in C and Perl, with C++ coming closely behind. Additionally, I've programmed in Ruby, Lisp, Scheme, Matlab and Ada. More on this here and here.

About 3 weeks ago, I've decided to give Python a try. During this time I have been intensively learning and using Python, so now I'm ready to give a list of my initial impressions.

First, a word on my learning process. Python is a mature and useful language, so from the start I decided not only to play around, but to take it quite seriously. So, apart from reading the official Python tutorial and most of the free online book Dive into Python I spent a lot of time actually using Python, both for writing test scripts that display various features I might need and useful programs, both at work and home. Here's a rough list of the code I've written to get familiar with Python, in no particular order:

Accessing Windows DLLs from Python code

GUIs with wxPython

Tools for working with files, paths and directories

Code involving threads and sockets

Various scripts to test how Python finds its modules and packages

Used py2exe to package scripts as self-contained .exe files

I've also written a couple of non-toy applications that actually do something useful:

wxPyTris – a Tetris clone

A simple GUI that can work as a XML -RPC client or (threaded) server

that can work as a -RPC client or (threaded) server A netlist / pinlist comparison utility useful for my work. I had it previously written in Perl, but now I've written a more feature-complete version in Python with a wxPython GUI

In total, I think I've written at least 3K lines of Python code and read a lot of documentation, newsgroup posts and tutorials. I'm still far from being proficient in Python, but I can now use it quite effectively.

My Python impressions

The impressions are divided to positive and negative, and inside each section there's no particular order.

What I like about Python

Significant indentation is actually a pretty good thing. Since I always pedantically indent my code anyway, I don't find it to be an impediment. On the contrary – it has some very desirable features: much less punctuation to type (braces, begin/end, etc.), and code written by others is usually easier to understand, because Python forces it to be structurally cleaner.

In a way, Python is openly supported by a large company that uses it extensively – Google. This means that there are a few smart people who get paid to develop and improve Python. For example Guido Von Rossum, the Python creator, works on Python in Google. I heard that the "release manager" for Python 2.6 also works for Google. This is important: while enthusiasts can create great tools in their free time, my experience tells me that to really perfect a tool, consistently, it is important for some people to earn their living from working on it.

The Python community doesn't treat Windows as a Nth-priority platform. All modules I've seen so far come with easy installers for Windows that just work. This is very important for me, as 95% of my work is being done on Windows.

The documentation is very good

PyCrust is a very helpful tool

wxPython – very mature and easy to use. The wxPython demo is amazing. Everything works very quickly, with beautiful native GUIs. wxPython is so good that most open-source Python IDEs seem to be written in pure Python + wxPython

Convenient built-in named arguments

Docstrings

The in operator

operator List comprehensions

Chained comparisons in expressions: (1 < x < 4) instead of (x > 1 and x < 4) . Remember that this feature really shines when you replace x by self.server.count_connections() :-)

instead of . Remember that this feature really shines when you replace by :-) Batteries included – the Python standard library has a lot in it, and this is a very good thing, especially when you want to quickly distribute your scripts to coworkers who have no idea about Python.

The way the print function works is quite convenient – it adds spaces between its arguments and a newline at the end, and thus saves boilerplate typing when debugging. And let's face it, print in Python is used mainly for debugging anyway (files are written with the write() method of file objects).

function works is quite convenient – it adds spaces between its arguments and a newline at the end, and thus saves boilerplate typing when debugging. And let's face it, in Python is used mainly for debugging anyway (files are written with the method of file objects). Python has native threads !! Although some restrictions on multi-CPU concurrency are imposed by the GIL , I understand that this can be solved in most cases. A nice feature of native threads is that waiting for a system call in one thread doesn't block the other threads (which happens with Ruby's green threads).

, I understand that this can be solved in most cases. A nice feature of native threads is that waiting for a system call in one thread doesn't block the other threads (which happens with Ruby's green threads). Excellent support for loading C/C++ DLLs. The standard ctypes module is very convenient and easy to use.

What I don't like about Python

Python doesn't have a large index of modules like Perl's CPAN . There's PyPi, but it appears to be both less complete and less universally used than CPAN .

. There's PyPi, but it appears to be both less complete and less universally used than . len() is a function and not a method of string. In general, Python is less consistent in this respect than, say, Ruby. Some operations are functions ( len , dir ), some built-in statements ( del ) and some object methods ( reverse , append , etc.)

is a function and not a method of string. In general, Python is less consistent in this respect than, say, Ruby. Some operations are functions ( , ), some built-in statements ( ) and some object methods ( , , etc.) string 's join method is OK, but why not also add a join method to a list. It is more elegant to write [1, 2, 3].join(',') than to write ', '.join[1, 2, 3]

's method is OK, but why not also add a method to a list. It is more elegant to write than to write The syntax for a single-item tuple is a parsing-imposed ugliness, akin to the need to separate the closing '>'s in C++ nested templates.

Lack of the ability to use ? and ! in identifiers. I came to like the Ruby way of naming predicates and destructive functions, and with Python I'm back to the C++/Perl dilemmas of isEmpty vs. empty vs. emptyp , etc. instead of the elegant empty?

vs. vs. , etc. instead of the elegant The unless keyword is sorely missing

keyword is sorely missing "Batteries included" also has a downside – there are a lot of clutter and deprecated libraries. While it's good for keeping backwards compatibility, for new users this is a bit inconvenient, because you're not always sure what to use.

I'm not particularly fond of the way private methods are called in Python. while I don't have a particular problem with methods receiving self and having to use it explicitly (it allows for some surprising flexibility, especially when passing around methods as callable objects), the syntax for private methods is too much on the fingers. Suppose your class has a private method called Foo. In C++, you'd call Foo() from another method in this class. In Python, you have to bang self.__Foo() . A bit too much. And while we're at it, I don't like those double underscor

Conclusion

All considered, I really like Python. The cons are mainly nits that are easy to overcome, while the pros are significant. I'll continue practicing Python, and will write a more organized review later on.