This would be better if abstract base classes were demonstrated. It's better to build a sequence class with collections.abc.Sequence, for instance, to avoid all that boilerplate.
This is a great, thorough overview. To me, the main omission is next / __next__. It was misnamed in Python 2 (corrected to be a "magic method" in Python 3) but belongs on the list nonetheless. It is the method of an iterator that returns the next item, and is core to (almost) any iterable object in Python (except sequences that can be sequentially indexed from zero).
> The use case for these magic methods might seem small, and that may very well be true. I won't spend too much more time on reflection magic methods because they aren't very important
If you want a reason to use the instancecheck magic method, the mocking of test objects is a good one. I recently came unstuck with testing Django models and mocking out DateFields, and the instancecheck method was the solution - http://tech.yunojuno.com/mocking-dates-with-django
1. Closing a file by relying on the, nondeterministic, GC seems like a cover-up solution for sloppy programming. I've seen quite a few C# code bases where people even, instead of closing, put the equivalent of assert(self.file.closed) inside the destructor to get an early warning when someone forgets to close an external handle.
2. Why call del self.file inside __del__? If the object itself is being destroyed that means anything self refers to will be useless already and the refcount should already be decremented.
Right, and since C# was brought up, a "using" statement is the equivalent way of making sure the resource is disposed of properly when it falls out of scope.
Sort of. CPython's main GC strategy is is refcounting, which is deterministic. It also does have a cycle-detecting GC that's not deterministic
But this is an implementation detail, so it could change in the future. And CPython isn't the only implementation, either. IronPython, pypy, and Jython all have different GC characteristics.
From the documentation of the Python 3.3 data model[1]:
> CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, .... Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become unreachable (ex: always close files).
> object.__del__(self) Called when the instance is about to be destroyed. This is also called a destructor. ... It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits.
Great article, definitely bookmarking this. I think it's important to give a reminder somewhere that modifying the magic methods really should be done with care. People new to Python could use this in a brute force way, when logic could do the trick.
Working for example with a framework like web2py, that re-implements a bunch of these, makes development slow and laborious sometimes.
From the very first section of the article ("Introduction"):
> They're also not as well documented as they need to be. All of the magic methods for Python appear in the same section in the Python docs, but they're scattered about and only loosely organized. There's hardly an example to be found in that section (and that may very well be by design, since they're all detailed in the language reference, along with boring syntax descriptions, etc.).
> So, to fix what I perceived as a flaw in Python's documentation, I set out to provide some more plain-English, example-driven documentation for Python's magic methods