Unsorted Random Notes
Method calls and interpreters
- Dunder (‘double under’)
__methods__are only meant to be called by Python interpreters, not by developers directly.__init__is the usual exception, called explicitly viasuper().__init__()in subclass constructors. - If you need to call a
__method__, it’s usually better to call the related built-in function (e.g.len,iter,str, etc.) rather than__len__()directly. - Sometimes, the
__method__andmethod()built-in produces different results. For example,list.sort()sorts a list in place and returnsNoneindicating that no new object was created, whilesorted(list)creates a new list and returns it. Theshuffles()built-in has the same behaviour assorted(). - Invocation of special methods by the interpreter is often implicit, and the dispatch chain can have fallbacks. For example,
for k in xfirst triesiter(x)(which callsx.__iter__); if__iter__is not defined, the interpreter falls back to the older sequence protocol and callsx.__getitem__(0),x.__getitem__(1), … untilIndexError. This is why classes implementing only__getitem__are still iterable. - Built-in types are often optimised for performance - take advantage of them when you can. The optimisation can bypass the special methods entirely: for built-ins like
listandstr, CPython reads theob_sizefield of thePyVarObjectstruct to get the length instead of calling__len__. This is transparent as long as you go through the built-in (len(obj)) rather than the dunder. __repr__and__str__- if you implement one, pick__repr__. It represents the string representation of the object, and you should be able to recreate the object from__repr__’s output. It’s also the fallback for__str__.