Recommended with reservations.
You have to know what you’re doing with this book. It’s a second edition dated 2020 in the Python 3.9 era, so it cannot be expected to cover the Ruff linter (released in 2022) nor some of the newer language features like structural pattern matching (Python 3.10) and of course some example setup scripts in the last chapter need updating.
The book starts off as a call to use idiomatic Python (docstrings, type hints etc) and then suddenly turns itself into something that feels like a different book entirely: the discussion of low-level internal representations of objects using descriptors was quite interesting, but unless you’re implementing something seriously close to the language I’d hesitate to call that ‘clean code’. Still it’s a good overview of some of the more advanced things you can do in the Python language, and the section on writing context managers and decorators looked useful. The chapters are supposed to be in increasing order of complexity but I’d have put chapters 3 and 4 before chapter 2 and perhaps moved chapter 7 earlier.
There is some wobbly code. I particularly don’t like the way it uses itertools.tee when the library documentation specifically says that if you plan to run through the whole of one of the iterators before starting the next then you’d be better off using a list, because that’s what “tee” will be doing under the hood if you can’t interleave your usage of its returned iterators; the book also doesn’t warn it’s not thread-safe. In another place it has a database handle which I’m not sure gets closed at EOF, and clearer imports would have been nice too (@wraps should probably have been explained earlier). The author ends the book by saying feel free to disagree, which I applaud but I will say to make sure you’re the kind of programmer who does before reading this book.
There are typos. Mostly these are minor annoyances in the sentences and incorrect syntax highlighting in some code strings, but sometimes it escalates to sentences that state the opposite of what was meant (for example, when duck typing comes up in the context of interfaces). There is overuse of the phrase “a long time ago” in the context of Python’s development (why not just look up the year and put that into the text?) and there are incorrect statements that unit tests constitute “formal proof” of a program’s correctness (no they’re not: look up formal verification; unit tests are merely evidence).
Also it’s not quite correct of them to imply in several places that circular references always cause memory leaks: this is true in instances where the cyclic garbage collector fails, usually if you’ve overridden destructors but can depend on the implementation and version, so it would be more correct to say there’s a small risk of memory leak on some implementations, and unless you know you have a memory problem I’d say their extensive use of weakref feels like premature optimisation.
There’s one suggestion the book makes that I really feel I must call out. Early on it says you can use an automatic code formatter to rewrite your entire Git history. Please do not do this. What if a bug in that formatting utility subtly changes what your code does, and you no longer have the history to help when you find it later? History rewrites are for when you accidentally committed large generated binaries or confidential secrets, not for gambling your entire codebase on an airbrushing exercise. Please let history happen as it did.
If a third edition of this book could address all of these things I could recommend it, otherwise it has to be at most with strong reservations. Incidentally, I reviewed the PDF so I’m unable to comment on the book’s physical durability etc but the typesetting was OK.
Website: https://www.packtpub.com/en-gb/product/clean-code-in-python-9781800560215
Code Site: https://github.com/PacktPublishing/Clean-Code-in-Python-Second-Edition










