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
- 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 - List comprehensions
- Chained comparisons in expressions:
(1 < x < 4)
instead of(x > 1 and x < 4)
. Remember that this feature really shines when you replacex
byself.server.count_connections()
:-) - 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 thewrite()
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).
- 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.
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.)string
'sjoin
method is OK, but why not also add ajoin
method to a list. It is more elegant to write[1, 2, 3].join(',')
than to write', '.join[1, 2, 3]
- 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 elegantempty?
- The
unless
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 callFoo()
from another method in this class. In Python, you have to bangself.__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.