(Review copy from Packt Publishing)
Preamble: re-reading this review I realise that it comes across as rather negative. Unfortunately, the things about this book which put me off put me off sufficiently that they outweighed the many parts which I did find useful. Since I know that there are quite a few other reviews around the Python community which are more positive, I don’t feel the need to recast anything in particular: prospective purchasers who aren’t deterred by the aspects which deterred me will find enough useful material in other reviews. My sincere compliments to the author on producing the book at all: I hope he considers my comments constructive and not merely negative or nit-picking.
When I first saw it being noised about, this book’s title (and its subtitle: “Best practices for designing, coding… “) suggested to me that its target audience was people who already had an amount of experience of Python and who wanted to learn some nifty tips and tricks and some good design practices in general. And I thought to myself that it was high time for such a book. It seems to me, without an exhaustive survey, that the majority of Python books out there are either in the “learn from scratch” camp or are aimed at a particular segment of the market: either a particular toolkit, such as Twisted or sqlalchemy; or a particular discipline, such as Bioinformatics. It’s almost as though, having launched you out into the mainstream of Python programming, you’re left to trawl the internet for resources.
The book falls into three main sections: the first few chapters covering various syntax choices, especially those which have been introduced more recently; the middle chapters covering a sort of project-management approach focusing a lot on the use of eggs and buildout; and a final section covering aspects of optimization and useful patterns. For reasons I’ll explain below, I find the first and last of the these sections the most useful and have less time for the central section.
To start a hare on python-list / python-tutor, you only need to ask a question like “What book should I read to learn Python?”. You’ll get as many answers as people who answer. Obviously there are a few favourites, but even these will have a detractor: someone who found it didn’t suit them at all. And that’s the way with books. One person likes every piece of illustrating code to be completely self contained; another prefers an example to run all the way through the book. One person prefers the code to be spelt out completely in the course of the book; another prefers a downloadable .zip or a CD. One person prefers a cookbook-style set of recipes; another prefers a more narrative approach punctuated with examples. One person prefers a jokey manner, littered with witty allusions and community in-jokes; another prefers a more straightforward just-tell-me-what-I-need-to-know style.
Expert Python Programming’s visual layout, font choices,etc. seemed to me a little pedestrian. The section headings are just a little too big, and the occasional pull-out [Notes] paragraphs remind me of late 1980s DTP more than I’d have expected for a professional publication. That the author’s first language isn’t English is apparent from the — extremely few — errors and very occasional awkwardness of style. (That his English is very good is equally apparent). None of this is showstopping, but it all forms part of the effect. I was surprised that the opening chapter detailed installing Python. I would have expected anyone reading a book on Expert Python Programming to have reached the point already where they could install Python and use it. Perhaps this is my misreading of the target audience. Likewise the advice on configuring a text editor (a notoriously personal issue).
The next few chapters cover newish syntax choices such as iterators, generators, decorators and context managers (contextors, anyone?). This is nicely pitched although I feel that the author is sometimes too didactic in his advice. For example: “Every time a loop is run to massage the contents of a sequence, try to replace it with a list comprehension”. Certainly, the “try” in that recommendation softens the effect slightly but he does the same thing a little later with generators which “should be considered every time you deal with a function that returns a sequence or works in a loop” (emphasised in the original). Again, the “considered” obviously doesn’t make it a mandate, but it does seem a little less nuanced that it might be. There are certainly places where you’ll trip yourself up if you just throw a generator at a sequence/loop.
This section includes a lot of examples, most small and self-contained and following the layout of an interpreter session. This is useful, although I feel that showing the entire interpreter session tends to introduce a lot of noise into the example (including all the “>>>” and “…” prompts. It also tends to result in quite vertically long code segments which will more easily cross over pages, making it more difficult to follow. Might work better if the font size was a point size smaller.
There follows a set of chapters covering syntax choices around classes, including subclassing built-in types, using super, slots and metaclasses. Possibly because this is an area where my own ignorance is more exposed I found the narrative and explanations here mostly useful. Unfortunately, stemming possibly from that same ignorance, I found the clutter in the code examples more noticeable and distracting. Try making sense, for example, of the explanation of a descriptor on page 75. Not sure what I’d have done to improve it, although removing the inline comments is probably not a bad idea especially as most of them are simple restatements of the next line of code.
Chapter 4 covers good naming and module / package organisation. And introduces the two things which I like perhaps most and least about this book: reference to useful external packages; and eggs. I like this reference to exernal tools because the stdlib doesn’t have everything – and nor should it, I say – and it’s always good to find out about tools other people have found useful. On the other side of the coin, I’m one of those people for whom setuptools / eggs and the subcommunity which has built around them are solving a problem I don’t have. That could be because I’ve never built a package with sufficient sophistication. But chapter 5 on “Writing a Package” plunges straight in with “Therefore, all packages can be built using egg structures” which I’m afraid put me off. Personally, I plan to go back and re-read this section when I’ve found myself trying to manage a package which is something more than a set of useful modules. As far as it goes, for those who are interested in learning about eggs and their interaction with PyPI, this chapter seems to give lots of practical advice. I would have preferred it to have started off slimline, showing a straightforward distutils setup.py without setuptools, without Paster.
Chapter 6 starts an application which runs through the rest of the book on-and-off: Atomisator, a feed aggregation toolkit. The author walks through creating the package, introduces sqlalchemy as a way to model the data and then discusses the API before talking about using a setup.py to declare interdependencies between subpackages and upload to PyPI. Chapter 7 extends this simple start by introducing zc.buildout, a build/release mechanism the author favours.
The next couple of chapters cover code management via version control systems – the author cannily focuses on Mercurial which has just been selected by GvR as Python’s VCS of the future. And speaks about continuous integration, showcasing buildbot, the Python-based system used by the Python core development among others. The chapters interleave higher-level explanations with low-level step-by-step installations. I feel that the latter actually detracts from the book a little: for one thing, projects move sufficiently fast that anyone reading this in a year’s time will very likely be seeing very different prompts and responses to those which the author illustrates. In addition, it leaves less space for real discussion of some key pros and cons or tips and tricks or Python-specific hints. Credit to the author, certainly, for being thorough, but I fear it could be counterproductive.
The next chapter neatly covers possible lifecycle models and illustrates the use of Trac as a project management tool: this is a nice choice as it’s a bit of a poster-child for Python and does lots of useful things well. Chapter 10 on Documenting is the free online chapter and I imagine many people had, like myself, read it before coming to the complete book. If one again cuts out the slightly over-explanatory example sections, this is the author at his best: there are concise and clear guidelines (for which he gives due credit to the author of Agile Documenting). More useful tools are introduced, including the invaluable Sphinx. Chapter 11 covers test-driven development and is nicely split into an “I Don’t Test” section followed by an “I do test” for new or existing converts, running over stdlib tools and nose / py.test. The chapter concludes with Fakes & Mocks and I think gives just the right amount of space to all of its sections and recommended tools: enough to give you a flavour of the tool without weighing you down with an extended example which might be better hosted on the tool’s own site.
The final section covers optimisation techniques, and covers approaches, data structures, caching, and multi-whatever programming touching on each one for long enough to give good enough feel of the pros and cons. More examples of useful tools which help to analyse the results of profiling and memory use. Here again I think the author’s approach shines: he’s doing a kind of question-and-answer session by himself and the motivation behind a number of the recommendations becomes a lot clearer. The very last chapter covers a number of the common Design Patterns, and I’m afraid I’ve never found the famous Patterns a particularly digestible topic so I’ll skip any commentary here.
In conclusion “Expert Python Programming” is definitely worth reading. If, like me, you’re not a fan of eggs and the like, then borrow it from a friend or the library lest you feel that you’ve wasted half the price. If you are a fan of eggs or are neutral, then buy the book. The best parts for my money are those where the author is covering speedily several different approaches or tools or issues and illustrating each one briefly.
As a postscript: the author’s examples are geared to Unix. Early on, he recommends installing MSYS and if you are a Windows user and a sufficient novice not to know what to substitute where, that might be your best solution. Personally I give MSYS & Cygwin the go-by as much as I can, unless forced (eg when trying build the ffmpeg libraries). Just one of those things.