Info Node: (python2.1-ref.info)Emulating numeric types
(python2.1-ref.info)Emulating numeric types
Emulating numeric types
-----------------------
The following methods can be defined to emulate numeric objects.
Methods corresponding to operations that are not supported by the
particular kind of number implemented (e.g., bitwise operations for
non-integral numbers) should be left undefined.
`__add__(self, other)'
`__sub__(self, other)'
`__mul__(self, other)'
`__div__(self, other)'
`__mod__(self, other)'
`__divmod__(self, other)'
`__pow__(self, other[, modulo])'
`__lshift__(self, other)'
`__rshift__(self, other)'
`__and__(self, other)'
`__xor__(self, other)'
`__or__(self, other)'
These functions are called to implement the binary arithmetic
operations (`+', `-', `*', `/', `%', `divmod()' , `pow()' , `**',
`<'`<', `>'`>', `&', `^', `|'). For instance, to evaluate the
expression X`+'Y, where X is an instance of a class that has an
`__add__()' method, `X.__add__(Y)' is called. Note that
`__pow__()' should be defined to accept an optional third argument
if the ternary version of the built-in `pow()' function is to be
supported.
`__radd__(self, other)'
`__rsub__(self, other)'
`__rmul__(self, other)'
`__rdiv__(self, other)'
`__rmod__(self, other)'
`__rdivmod__(self, other)'
`__rpow__(self, other)'
`__rlshift__(self, other)'
`__rrshift__(self, other)'
`__rand__(self, other)'
`__rxor__(self, other)'
`__ror__(self, other)'
These functions are called to implement the binary arithmetic
operations (`+', `-', `*', `/', `%', `divmod()' , `pow()' , `**',
`<'`<', `>'`>', `&', `^', `|') with reflected (swapped) operands.
These functions are only called if the left operand does not
support the corresponding operation. For instance, to evaluate
the expression X`-'Y, where Y is an instance of a class that has
an `__rsub__()' method, `Y.__rsub__(X)' is called. Note that
ternary `pow()' will not try calling `__rpow__()' (the coercion
rules would become too complicated).
`__iadd__(self, other)'
`__isub__(self, other)'
`__imul__(self, other)'
`__idiv__(self, other)'
`__imod__(self, other)'
`__ipow__(self, other[, modulo])'
`__ilshift__(self, other)'
`__irshift__(self, other)'
`__iand__(self, other)'
`__ixor__(self, other)'
`__ior__(self, other)'
These methods are called to implement the augmented arithmetic
operations (`+=', `-=', `*=', `/=', `%=', `**=', `<'`<=', `>'`>=',
`&=', `^=', `|='). These methods should attempt to do the
operation in-place (modifying SELF) and return the result (which
could be, but does not have to be, SELF). If a specific method is
not defined, the augmented operation falls back to the normal
methods. For instance, to evaluate the expression X`+='Y, where X
is an instance of a class that has an `__iadd__()' method,
`X.__iadd__(Y)' is called. If X is an instance of a class that
does not define a `__iadd()' method, `X.__add__(Y)' and
`Y.__radd__(X)' are considered, as with the evaluation of X`+'Y.
`__neg__(self)'
`__pos__(self)'
`__abs__(self)'
`__invert__(self)'
Called to implement the unary arithmetic operations (`-', `+',
`abs()' and `~{}').
`__complex__(self)'
`__int__(self)'
`__long__(self)'
`__float__(self)'
Called to implement the built-in functions `complex()' , `int()' ,
`long()' , and `float()' . Should return a value of the
appropriate type.
`__oct__(self)'
`__hex__(self)'
Called to implement the built-in functions `oct()' and `hex()' .
Should return a string value.
`__coerce__(self, other)'
Called to implement "mixed-mode" numeric arithmetic. Should either
return a 2-tuple containing SELF and OTHER converted to a common
numeric type, or `None' if conversion is impossible. When the
common type would be the type of `other', it is sufficient to
return `None', since the interpreter will also ask the other
object to attempt a coercion (but sometimes, if the implementation
of the other type cannot be changed, it is useful to do the
conversion to the other type here).
*Coercion rules*: to evaluate X OP Y, the following steps are taken
(where `__OP__()' and `__rOP__()' are the method names corresponding to
OP, e.g., if OP is ``+'', `__add__()' and `__radd__()' are used). If
an exception occurs at any point, the evaluation is abandoned and
exception handling takes over.
* 0. If X is a string object and OP is the modulo operator (%), the
string formatting operation is invoked and the remaining steps are
skipped.
* 1. If X is a class instance:
* 1a. If X has a `__coerce__()' method: replace X and Y with
the 2-tuple returned by `X.__coerce__(Y)'; skip to step 2 if
the coercion returns `None'.
* 1b. If neither X nor Y is a class instance after coercion,
go to step 3.
* 1c. If X has a method `__OP__()', return `X.__OP__(Y)';
otherwise, restore X and Y to their value before step 1a.
* 2. If Y is a class instance:
* 2a. If Y has a `__coerce__()' method: replace Y and X with
the 2-tuple returned by `Y.__coerce__(X)'; skip to step 3 if
the coercion returns `None'.
* 2b. If neither X nor Y is a class instance after coercion,
go to step 3.
* 2b. If Y has a method `__rOP__()', return `Y.__rOP__(X)';
otherwise, restore X and Y to their value before step 2a.
* 3. We only get here if neither X nor Y is a class instance.
* 3a. If OP is ``+'' and X is a sequence, sequence
concatenation is invoked.
* 3b. If OP is ``*'' and one operand is a sequence and the
other an integer, sequence repetition is invoked.
* 3c. Otherwise, both operands must be numbers; they are
coerced to a common type if possible, and the numeric
operation is invoked for that type.