Why I am not really fond of docstrings in Python
I wrote some nice things before about how I don't really use docstrings, but in thinking about it more I've realized that I was shading the truth. The real truth is that I don't really like using docstrings, and I've recently figured out why: docstrings don't stand out enough.
(I have to say here that I have nothing against documenting my code; I just want it to look right.)
Unless you use an editor and display environment that set docstrings off quite distinctly, docstrings look a lot like code (strange code, admittedly); there is nothing particular in their indentation or the start of the line that makes them stand out. Thus, it is sort of like reading Lisp for me: I have to pay attention to notice docstrings and make sure I am not merging docstrings and code together.
By contrast, comments have a quite visible marker in Python; when you are skimming code, it's very difficult to mistake a comment for code or miss a comment in the code. It is easy to page through a file looking only at comments (or only comments at a certain indentation level, or with a certain sort of formatting), or ignoring comments, much easier than doing the same thing with docstrings (without editor support).
(And I don't think it's an accident that common commenting methods in C do the same thing, despite it not being required. I think that people actively want comments to stand out quite distinctly, and this is probably one reason for the enduring popularity of 'start of line' comment markers in all sorts of programming languages.)
(This was crystalized by reading this entry and having the light suddenly go on about why my gut was curdling at the thought of lots of docstring usage to make my code look better, because I realized that I felt that it would actually make it look worse.)
In passing, I will note one advantage I see in docstrings being more merged into the code: it probably encourages a certain amount of terseness in function documentation. Speaking from personal experience, it's very easy to ramble on in comments, especially comments between functions, since they aren't all that distracting when I'm looking at the code.
More thinking about Python's inheritance model
Here's something I've been pondering lately: why doesn't Python have
an inheritance model more like C++, where (for
example) your superclass's
__init__ is automatically called?
There's a number of reasons, but I think that one of them is that Python lacks any concept of private class attributes and methods. When you limit what a subclass can do to a superclass, when you have private internal state that has to be maintained correctly, it's clear that you cannot let a subclass block the correct initialization (or destruction) of a parent class. So you have to call the superclass's initializer, and in fact you have to call them from the top of the inheritance tree on down, because you need to prevent the subclass from getting control before the superclass is ready for it.
(To develop this argument slightly more: it doesn't do any good to protect an instance attribute or a class method if you don't also protect the thing's dependencies, and one of the core dependencies is a correctly initialized object. Or in short: protecting the value of an instance attribute is pointless if you don't also protect the fact that it has a defined value.)
Since Python gives classes no such protection it is free to adopt a simpler model of class inheritance, because it is not giving subclasses any power that they don't already have. (And you can argue that the simpler model is also more powerful, since it allows Python subclasses to do things that would probably be impossible in C++.)
(Disclaimer: the author doesn't actually know C++, although he keeps intending to learn it.)