langston-barrrett.github.io
Python Style Guide
This is my personal style guide for writing Python code. As with all style guides, this guide is incomplete, fallible, and its recommendations aren't appropriate for every circumstance.
I've only recently started writing this, so it's obviously particularly incomplete. Hopefully, it will grow as I learn and think more!
This guide is focused only on recommendations that aren't universal across programming languages, for such recommendations see my [Programming Style Guide](programming.org::*Programming Style Guide). Additionally, I don't currently publish any recommendations that concern third-party libraries.
Its intended audience is intermediate or advanced Python programmers who endeavor especially to write reliable, correct code. In particular, I'm often willing to err on the side of reliability over "Pythonic" or "idiomatic" code, e.g., by changing code so that it can get more mileage/guarantees from a static type checker like Mypy, or by using less mutation than might be "expected". But to be honest, I mostly publish this so I have somewhere with thorough explanations that I can point people to when I make comments during code reviews.
The recommendations in this guide are split into three levels, based on the author's perception of their relative importance and applicability:
- Strongly Recommended: These recommendations are broadly applicable and have a high value-to-weight ratio.
- Recommended: These recommendations may apply less universally, or be less than essential to a strong style guide.
- Nice to Have: These recommendations are nice but not essential.
This document aspires to confirm to my Meta Style Guide.
Do you have ideas for this guide? Contact me!
Strongly Recommended
Recommended
Use Dataclasses
Every class should be annotated with the dataclasses.dataclass
decorator
(doc)
unless there is a specific reason not to. This still applies if you have
to write an __init__
method.
-
Example
Instead of
class C: def __init__(self, x: int) -> None: self.x = x
write
@dataclass class C: x: int
-
Justification
The
dataclass
decorator can generate all sorts of "dunder" methods that you normally have to write by hand, such as__init__
and__eq__
. This saves both the writer and reader of the code some time!Dialing in on
__eq__
: the implementation generated bydataclass
compares instances of the class field-wise. This is almost universally more meaningful than pointer/reference equality, which is the default for classes that inherit fromobject
. Consider this example:C(5) == C(5)
With the former implementation of
C
, this evaluates toFalse
whereas with thedataclass
version it evaluates toTrue
. If you think this is unimportant because you don't intend to compare instances of your class for equality, consider overriding the__eq__
method manually and raising an exception if it gets called to make that assumption explicit. If you don't do that, strongly consider usingdataclass
.