Inheritance gives a subclass everything, including what it should not have. The penguin problem, and what to do instead.
The question is only ever what the method needs — this instance, the class, or neither. Getting it wrong quietly breaks subclasses.
Python has no need for getters and setters, because @property lets you add validation later without changing a single caller.
A class without __repr__ wastes your time from the moment it exists. repr is for you, str is for the reader, and one of them has a sensible fallback.
self is a parameter name, not a keyword. __init__ does not create the object. And a class attribute is shared until the moment you assign through an instance.
Most classes in Python should have been functions. The test is not “is this a noun” — it is whether there is invalid state a class can prevent.
What the f actually compiles to, the whole format spec language, __format__, and the three jobs an f-string is the wrong tool for. Every output run on Python 3.12.
Three tools from the collections module that replace loops you have written by hand many times, and the one defaultdict behaviour that surprises people.
One decorator writes __init__, __repr__ and __eq__ for you. Defaults, frozen instances, ordering, post-init and the default_factory rule.
What with guarantees, how to write __enter__ and __exit__, the contextlib shortcut, and how to swallow an exception on purpose.