1 Intro
My intention for this article is to be a quick-reference guide: all the information you might need about a method or property condensed into a few lines. This might not be possible for something like __slots__, perhaps we should link to the Python Docs for details on the more complex ones. I know this stuff is documented in other places (for example, http://docs.python.org/ref/specialnames.html), but it's all over the place and hard to mentally parse. I want to teach while at the same time to be brief, if that is possible.
Anyways feel free to add, don't worry about messing stuff up, I can always revert your edits if I really hate them ; ) A list of underscore methods that I haven't written about yet is at the bottom; there might be more too that I don't know about. And things I'm not sure about have question marks next to them, feel free to search for question marks and correct any uncertainties.
2 Class and Instance Methods
For consistency's sake, let's say we have a class called 'Class', instances called 'x' and 'y'. Keeping with the Python docstrings, '<==>' can be read as 'is equivalent to'.
2.1 Creation, Calling, and Destruction
2.2 Conversion to Strings
2.3 Truth Testing
2.4 Comparisons
For instances to be meaningfully sorted, either __cmp__, __lt__, or __gt__ must be defined. If more than one is defined, __lt__ will be tried first, followed by __gt__ and then finally __cmp__.
2.4.1 "Rich Comparison" Operators
The following functions customarily return True or False, but can return any value. If in a boolean context, Python will call bool() on the returned value to determine truthfulness. NotImplemented should be raised if no valid comparison can be made.
If one of these methods is not defined, Python will try the opposite method with swapped arguments. For example, if you call x < other but x.__lt__ is not defined, Python will try the equivalent other.__gt__(x). If neither is not defined, x.__cmp__(other) will be tried, followed by other.__cmp__(x). If all four methods are undefined, instances are compared by object identity (address?).
Note that no other fallbacks will be performed. For example, if __le__ is not defined, Python does not call lt and eq. Similarly, Python will not fallback to __ne__ if __eq__ is not defined, or vice versa -- this can result in two instances that are 'equal' and 'not equal' at the same time.
There are no explicit 'reflected' (swapped-argument) versions of the comparison operators.
2.5 Logical and Mathematical Operators
2.5.1 Regular Binary Operations
These methods implment the binary operators +, -, , /, //, %, *, <<, >>, &, |, and ^, and the functions divmod and pow.
The method may raise NotImplemented if no operation is possible with the supplied with the supplied argument(s).
If not defined or if returns NotImplemented, and the two instances belong to different classes, Python will try to call the equivalent reflected binary operator method of the other instance, with this instance as the argument.
If that method is also not defined, the relevant operation is not possible and a TypeError ('unsupported operand type') is raised.
2.5.2 Reversed Binary Operations
These methods implement, with swapped commands, the binary operators +, -, , /, //, %, *, <<, >>, &, |, and ^, and the functions divmod and pow. They are only called if the target's equivalent regular binary operator is not defined or returns NotImplemented.
In other words, if y + x is executed, and y.__add__ is not defined, and y and x are of different types, Python will attempt to call x.__radd__(y).
The method may raise NotImplemented if no operation is possible with the supplied with the supplied argument(s).
If not defined, the relevant operation is not possible and a TypeError ('unsupported operand type') is raised.
2.5.3 In-Place Binary Operations
These methods implement the in-place binary operators +=, -=, *=, /=, //=, %=, **=, <<=, >>=, &=, |=, and ^=. Note that there is no in-place equivalent for divmod, while pow is only available as **=.
The method should attempt to modify the instance (self) in place and return the result. In any case, Python assigns the result as the new value of the instance.
It may raise NotImplemented if no operation is possible with the supplied with the supplied argument(s).
If method is not defined or returns NotImplemented, the equivalent operation is attempted with the the equivalent regular binary operator. If that is not defined or returns NotImplemented, and the two instances are of different types, the equivalent reflected binary operator method of the other instance is called.
If none of the three is defined or don't raise Not Implemented, the operation is not possible and a TypeError ('unsupported operand type') is raised.
For example, if x += other is attempted, x.__iadd__(other) is tried first, followed by x.__add__(other) and then other.__radd__(x).
2.5.4 Unary Operations
2.6 Casts
These methods implement conversion to various numeric types. One of these methods is called when the corresponding built-in method is called with the instance. If no conversion is possible, a ValueError can be raised (?) (not sure if this is official, but that's what strings do). If not present, the specified conversion cannot be done and an AttributeError is raised.
2.6.1 Real Numbers
In these methods, if the incorrect type is returned, a TypeError is raised (e.g., "__float__ returned non-float").
2.6.1.1 Slice Indices
2.6.2 Complex Numbers
2.7 Containing Items
2.7.1 Basics
Although not required, it's probably a good idea to implement these if your instances will contain user-accessible items.
2.7.2 Items and Slices
These methods are called when bracket notation is used.
Python will behave differently depending on the type of value inside of the brackets:
-
x[key], where
key is a single value
- Calls x.__*item__(key) x[start:end] where x.__*slice__ exists
- Calls x.__*slice__(cooked_start, cooked_end) where start and end are 'cooked' as described below in 'Old-Style Slices' x[start:end] where x.__*slice__ does not exist, or x[extended_slice], where extended slice is any slice more complex than start:end
- Calls x.__*item__ with slice object, Ellipsis, or list of these.
2.7.2.1 Items and New-Style Slices
In general, if key is of an inappropriate type, TypeError should be raised. If it is outside the sequence of keys in instance, IndexError should be raised. If instance is a mapping object and key cannot be found, KeyError should be raised. (What if neither of these is true? I don't know.)
2.7.2.2 Old-Style Slices
These methods are depreciated but still widely used. Furthermore, for simple slicing Python checks for their existence first before calling the __*item__ methods.
For these methods, Python 'cooks' the indexes before passing them. Negative slice indexes are converted to (usually) positive ones by adding them to the value returned by __len__, and so if __len__ is not defined, negative slice indexes cannot be used. Furthermore, an empty start index is replaced by 0, and an empty end index by sys.maxint.
2.8 Attribute Access
As an alternative to Containing Items, instance attributes can be directly read, written to, and deleted. Access can be customized using these methods.
2.9 Being Contained By Another Object
2.9.1 Descriptors
New-style classes may possess attributes called "descriptors", which are themselves new-style class instances. With the following functions, descriptors can change what will happen when the descriptor is accessed, set, or deleted.
Note: to work in this fashion, a descriptor must be possessed by a class, not by an instance.
For the following examples, assume we have a new-style container class called 'Container' with an instance called 'container'. Also note that instance is the container class instance that the descriptor was accessed through, or None if the descriptor was accessed through the class itself. owner is the actual owner of the descriptor (the container class itself).
2.10 Pickling
The pickle protocol provides a standard way to serialize and de-serialize objects. These functions customize the pickling of class instances.
For all the gooey details (trust me they're gooey), see PEP 307 -- Extensions to the Pickle Protocol
2.10.1 Serializing and Unserializing Data
These functions are only called if class is old-style or __reduce__ and __reduce_ex__ are undefined.
2.10.2 Customizing Object Creation upon Unpickling
2.10.3 Total Control
These methods work for new-style classes only.
2.10.4 One More Thing
2.11 Copying
__copy__ __deepcopy__
2.12 "With" Statements
__enter__ __exit__
2.13 Really Complicated
__new__ __coerce__
3 Class Methods
__subclasses__, see http://lucumr.pocoo.org/blogarchive/python-plugin-system
4 Class & Instance Properties
__dict__ & vars() __class__ __metaclass__ __bases__ __name__ __slots__ __weakref__
5 Class & Function Properties
__doc__
6 File Properties
__file__
7 Builtin Functions
__import__
8 Module Properties
__builtins__ (nonstandard, see http://docs.python.org/lib/module-builtin.html) __all__
9 Modules
__builtin__ __main__ (represents scope of main program, http://docs.python.org/lib/module-main.html) __future__
10 Other Things I've Seen Around
__requires__ __traceback_hide__ __debug__
11 Talk about in Intro/Conclusion?
- dir()
- object
- property/fget/fset/fdel