MCS 275 Spring 2024
        Emily Dumas
    
Adding special methods lets a custom class work with built-in operations like +, *, len, abs, ...
These methods get called automatically when we apply addition, multiplication, etc., to instances.
| Operation | Special method | |
|---|---|---|
| A==B | A.__eq__(B) | |
| A+B | A.__add__(B) | |
| A-B | A.__sub__(B) | |
| A*B | A.__mul__(B) | |
| A/B | A.__truediv__(B) | |
| A**B | A.__pow__(B) | 
List of many more in the Python documentation.
| Operation | Special method | |
|---|---|---|
| str(A) | A.__str__() | |
| len(A) | A.__len__() | |
| abs(A) | A.__abs__() | |
| bool(A) | A.__bool__() | |
| A[k] | A.__getitem__(k) | |
| A[k]=v | A.__setitem__(k,v) | 
Point2 — point in the plane (a location in 2D)Vector2 — vector in the plane (e.g. the displacement between two points)This is all going in an example module oop/plane.py in the course code repo.
 
     
    isinstance(obj,classname) -- returns bool indicating whether obj is an instance of the named class (or subclass thereof)NotImplemented -- Special value that operators should return if the operation is not supportedIn evaluating A+B, Python first tries
        
A.__add__(B)NotImplemented), it will try
        B.__radd__(A)There are "reflected" versions of all the binary operations (e.g. __rmul__).
Overloading is best used when a function or operator has a clear, natural meaning for a class.
If used too much or in unintuitive ways, it makes programs harder to understand.
When a class is designed so that it only ever has one instance, the class (or the only instance of it) is called a singleton.
We've seen two of these so far:
None, the only instance of NoneTypeNotImplemented, the only instance of NotImplementedType