Serious Python by Julien Danjou is an excellent book for those who have gone through the "hello world" tutorials or those coming to Python from other programming languages, and want a book that teaches you not just how to write code, but how to write code the pythonic way.
You won't find chapters on mere syntax in this book: it expects that you've already covered the basics and want to move your Python skills to the next level. This covers a lot of ground that other Python books don't, and I'm glad I have it on my digital bookshelf.
Chapter 1 covers laying out the files and folders for your Python project. This chapter was great, even for an experienced software developer like myself. I always threw everything into "src" and "docs" folders, but didn't quite understand how Python projects were formatted and, more importantly, why. And while I had heard about semantic versioning before, this book pointed out a couple things that I've been doing wrong with my version numbering for my entire career.
Chapter 2 covers modules and importing, which is especially helpful from other languages that have similar, but distinct, ways of importing code.
Chapter 3 covers not just documentation, but Python-specific documentation: the Sphinx tool, ReStructured Text, Sphinx extensions like autodoc and autosummary, and the warnings module. These are things I had been ignorant about for years while I was writing Python code, and it's great to find all this information in one place.
Chapter 4 covers timestamps and time zones, and this is not just important Python information, but important programming information. Most programmers only learn about basic time/date-related functions and stop there. Time zones and the Olsen database and how to *properly* handle them are often ignored, resulting in subtle and hard-to-debug problems in software. Chapter 4 brings all of these issues to light, along with easy-to-miss Python modules that make working with dates and timezones manageable.
Chapter 5 covers packaging and distributing Python code, which is especially complex given Python's history of various and overlapping package management tools. I wish there had been more information in this chapter, but it does act as a good introduction to a topic that you'd ordinarily only find out about piecemeal over a career.
Chapter 6 covers unit testing (with pytest), fixtures, and mocks. It also covers code coverage.py tool for measuring the effectiveness of your unit tests.
Chapter 7 covers decorators and static/class/abstract methods. This was a great chapter for me in particular, because it's a topic that I've been getting by on by copy/pasting decorator code from other projects and, while that worked, I didn't have a full understanding of *why* the code worked until I read this chapter. The same applies to static and class methods in Python, which are easy to misuse.
Chapter 8 covers functional programming concepts. While Python isn't a functional programming language, it does have many features that support (and benefit from) writing code in a functional style. For anyone who doesn't know about functional programming, or was burned before when trying to learn the topic, this is a must-read chapter.
Chapter 9 is the only chapter that I feel like isn't absolutely required reading. It's nice to have a chapter on abstract syntax trees (especially since Python comes with the ast module to help navigate Python code), but it isn't relevant to most programmers. Still, I'd rather read this chapter than try to find out about the topic from some random web tutoiral.
Chapter 10 covers performance and optimization, explaining not just the cProfile module but also the dis module for disassembling Python bytecode for analysis. While this might not be directly necessary for most performance improvements, it does give a good introduction to the idea that Python bytecode isn't mystical at all; and you can directly compare how different bits of Python code are compiled to bytecode. There's also a hefty list of need-to-know, Python-specific tricks to writing faster code.
Chapter 11 and 12 cover process and databases, respectively. I wish these chapters were longer, but like many of the short sections, they provide a good introduction to several concepts that many programmers are unaware of, so they are worth a read-through.
Chapter 13 covers a few miscellaneous topics that don't quite fit in any other chapter, but I'm glad he covers them. Context managers, unicode, data classes (using the attrs module), and Python 2/3 support are definitely important to have in your Python toolbox.
This book could easily have been ten times its current length, but I like that it is to the point and it does a great job guiding the reader through the most important topics that aren't always covered by other books. "Serious Python" is a book you need to read if you're serious about following mature processes and being a capable Python programmer. It's filled with practical information that's normally scattered across web tutorials, conference talks, and Stack Overflow posts, but has been compiled here into one an excellent book. 5 stars.
(Full disclosure: I'm an author for No Starch Press, but No Starch Press didn't ask me to write this review and I purchased a copy on my own.)Amazon review link