(window.webpackJsonp=window.webpackJsonp||[]).push([[2758],{3166:function(t,s,a){"use strict";a.r(s);var n=a(31),e=Object(n.a)({},(function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"overloading"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#overloading"}},[t._v("#")]),t._v(" Overloading")]),t._v(" "),a("h2",{attrs:{id:"operator-overloading"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#operator-overloading"}},[t._v("#")]),t._v(" Operator overloading")]),t._v(" "),a("p",[t._v("Below are the operators that can be overloaded in classes, along with the method definitions that are required, and an example of the operator in use within an expression.")]),t._v(" "),a("p",[a("strong",[t._v("N.B. The use of "),a("code",[t._v("other")]),t._v(" as a variable name is not mandatory, but is considered the norm.")])]),t._v(" "),a("table",[a("thead",[a("tr",[a("th",[t._v("Operator")]),t._v(" "),a("th",[t._v("Method")]),t._v(" "),a("th",[t._v("Expression")])])]),t._v(" "),a("tbody",[a("tr",[a("td",[a("code",[t._v("+")]),t._v(" Addition")]),t._v(" "),a("td",[a("code",[t._v("__add__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 + a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("-")]),t._v(" Subtraction")]),t._v(" "),a("td",[a("code",[t._v("__sub__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 - a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("*")]),t._v(" Multiplication")]),t._v(" "),a("td",[a("code",[t._v("__mul__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 * a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("@")]),t._v(" Matrix Multiplication")]),t._v(" "),a("td",[a("code",[t._v("__matmul__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 @ a2")]),t._v(" ("),a("strong",[t._v("Python 3.5")]),t._v(")")])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("/")]),t._v(" Division")]),t._v(" "),a("td",[a("code",[t._v("__div__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 / a2")]),t._v(" ("),a("strong",[t._v("Python 2 only")]),t._v(")")])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("/")]),t._v(" Division")]),t._v(" "),a("td",[a("code",[t._v("__truediv__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 / a2")]),t._v(" ("),a("strong",[t._v("Python 3")]),t._v(")")])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("//")]),t._v(" Floor Division")]),t._v(" "),a("td",[a("code",[t._v("__floordiv__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 // a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("%")]),t._v(" Modulo/Remainder")]),t._v(" "),a("td",[a("code",[t._v("__mod__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 % a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("**")]),t._v(" Power")]),t._v(" "),a("td",[a("code",[t._v("__pow__(self, other[, modulo])")])]),t._v(" "),a("td",[a("code",[t._v("a1 ** a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("<<")]),t._v(" Bitwise Left Shift")]),t._v(" "),a("td",[a("code",[t._v("__lshift__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 << a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v(">>")]),t._v(" Bitwise Right Shift")]),t._v(" "),a("td",[a("code",[t._v("__rshift__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 >> a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("&")]),t._v(" Bitwise AND")]),t._v(" "),a("td",[a("code",[t._v("__and__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 & a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("^")]),t._v(" Bitwise XOR")]),t._v(" "),a("td",[a("code",[t._v("__xor__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 ^ a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("|")]),t._v(" (Bitwise OR)")]),t._v(" "),a("td",[a("code",[t._v("__or__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 | a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("-")]),t._v(" Negation (Arithmetic)")]),t._v(" "),a("td",[a("code",[t._v("__neg__(self)")])]),t._v(" "),a("td",[a("code",[t._v("-a1")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("+")]),t._v(" Positive")]),t._v(" "),a("td",[a("code",[t._v("__pos__(self)")])]),t._v(" "),a("td",[a("code",[t._v("+a1")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("~")]),t._v(" Bitwise NOT")]),t._v(" "),a("td",[a("code",[t._v("__invert__(self)")])]),t._v(" "),a("td",[a("code",[t._v("~a1")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("<")]),t._v(" Less than")]),t._v(" "),a("td",[a("code",[t._v("__lt__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 < a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("<=")]),t._v(" Less than or Equal to")]),t._v(" "),a("td",[a("code",[t._v("__le__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 <= a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("==")]),t._v(" Equal to")]),t._v(" "),a("td",[a("code",[t._v("__eq__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 == a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("!=")]),t._v(" Not Equal to")]),t._v(" "),a("td",[a("code",[t._v("__ne__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 != a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v(">")]),t._v(" Greater than")]),t._v(" "),a("td",[a("code",[t._v("__gt__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 > a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v(">=")]),t._v(" Greater than or Equal to")]),t._v(" "),a("td",[a("code",[t._v("__ge__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a1 >= a2")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("[index]")]),t._v(" Index operator")]),t._v(" "),a("td",[a("code",[t._v("__getitem__(self, index)")])]),t._v(" "),a("td",[a("code",[t._v("a1[index]")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("in")]),t._v(" In operator")]),t._v(" "),a("td",[a("code",[t._v("__contains__(self, other)")])]),t._v(" "),a("td",[a("code",[t._v("a2 in a1")])])]),t._v(" "),a("tr",[a("td",[a("code",[t._v("(*args, ...)")]),t._v(" Calling")]),t._v(" "),a("td",[a("code",[t._v("__call__(self, *args, **kwargs)")])]),t._v(" "),a("td",[a("code",[t._v("a1(*args, **kwargs)")])])])])]),t._v(" "),a("p",[a("strong",[t._v("The optional parameter "),a("code",[t._v("modulo")]),t._v(" for "),a("code",[t._v("__pow__")]),t._v(" is only used by the "),a("code",[t._v("pow")]),t._v(" built-in function.")])]),t._v(" "),a("p",[t._v("Each of the methods corresponding to a "),a("strong",[t._v("binary")]),t._v(' operator has a corresponding "right" method which start with '),a("code",[t._v("__r")]),t._v(", for example "),a("code",[t._v("__radd__")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("A")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__init__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" a"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" a\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__add__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("a "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" other\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__radd__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"radd"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" other "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("a\n\nA"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Out: 3")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" A"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# prints radd. Out: 3")]),t._v("\n\n")])])]),a("p",[t._v("as well as a corresponding inplace version, starting with "),a("code",[t._v("__i")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("B")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__init__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" b"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" b\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__iadd__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("b "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" other\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"iadd"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" self\n\nb "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" B"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nb"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("b "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Out: 2")]),t._v("\nb "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# prints iadd")]),t._v("\nb"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("b "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Out: 3")]),t._v("\n\n")])])]),a("p",[t._v("Since there's nothing special about these methods, many other parts of the language, parts of the standard library, and even third-party modules add magic methods on their own, like methods to cast an object to a type or checking properties of the object. For example, the builtin "),a("code",[t._v("str()")]),t._v(" function calls the object's "),a("code",[t._v("__str__")]),t._v(" method, if it exists.\nSome of these uses are listed below.")]),t._v(" "),a("table",[a("thead",[a("tr",[a("th",[t._v("Function")]),t._v(" "),a("th",[t._v("Method")]),t._v(" "),a("th",[t._v("Expression")])])]),t._v(" "),a("tbody",[a("tr",[a("td",[t._v("Casting to "),a("code",[t._v("int")])]),t._v(" "),a("td",[a("code",[t._v("__int__(self)")])]),t._v(" "),a("td",[a("code",[t._v("int(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("Absolute function")]),t._v(" "),a("td",[a("code",[t._v("__abs__(self)")])]),t._v(" "),a("td",[a("code",[t._v("abs(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("Casting to "),a("code",[t._v("str")])]),t._v(" "),a("td",[a("code",[t._v("__str__(self)")])]),t._v(" "),a("td",[a("code",[t._v("str(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("Casting to "),a("code",[t._v("unicode")])]),t._v(" "),a("td",[a("code",[t._v("__unicode__(self)")])]),t._v(" "),a("td",[a("code",[t._v("unicode(a1)")]),t._v(" (Python 2 only)")])]),t._v(" "),a("tr",[a("td",[t._v("String representation")]),t._v(" "),a("td",[a("code",[t._v("__repr__(self)")])]),t._v(" "),a("td",[a("code",[t._v("repr(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("Casting to "),a("code",[t._v("bool")])]),t._v(" "),a("td",[a("code",[t._v("__nonzero__(self)")])]),t._v(" "),a("td",[a("code",[t._v("bool(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("String formatting")]),t._v(" "),a("td",[a("code",[t._v("__format__(self, formatstr)")])]),t._v(" "),a("td",[a("code",[t._v('"Hi {:abc}".format(a1)')])])]),t._v(" "),a("tr",[a("td",[t._v("Hashing")]),t._v(" "),a("td",[a("code",[t._v("__hash__(self)")])]),t._v(" "),a("td",[a("code",[t._v("hash(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("Length")]),t._v(" "),a("td",[a("code",[t._v("__len__(self)")])]),t._v(" "),a("td",[a("code",[t._v("len(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("Reversed")]),t._v(" "),a("td",[a("code",[t._v("__reversed__(self)")])]),t._v(" "),a("td",[a("code",[t._v("reversed(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("Floor")]),t._v(" "),a("td",[a("code",[t._v("__floor__(self)")])]),t._v(" "),a("td",[a("code",[t._v("math.floor(a1)")])])]),t._v(" "),a("tr",[a("td",[t._v("Ceiling")]),t._v(" "),a("td",[a("code",[t._v("__ceil__(self)")])]),t._v(" "),a("td",[a("code",[t._v("math.ceil(a1)")])])])])]),t._v(" "),a("p",[t._v("There are also the special methods "),a("code",[t._v("__enter__")]),t._v(" and "),a("code",[t._v("__exit__")]),t._v(" for context managers, and many more.")]),t._v(" "),a("h2",{attrs:{id:"magic-dunder-methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#magic-dunder-methods"}},[t._v("#")]),t._v(" Magic/Dunder Methods")]),t._v(" "),a("p",[t._v("Magic (also called dunder as an abbreviation for double-underscore) methods in Python serve a similar purpose to operator overloading in other languages. They allow a class to define its behavior when it is used as an operand in unary or binary operator expressions. They also serve as implementations called by some built-in functions.")]),t._v(" "),a("p",[t._v("Consider this implementation of two-dimensional vectors.")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" math\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Vector")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# instantiation")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__init__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" x"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("y "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" y\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# unary negation (-v)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__neg__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" Vector"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("y"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# addition (v + u)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__add__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" Vector"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("y "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("y"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# subtraction (v - u)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__sub__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" self "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# equality (v == u)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__eq__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("and")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("y "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("y\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# abs(v)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__abs__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" math"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("hypot"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("y"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# str(v)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__str__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'<{0.x}, {0.y}>'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("format")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# repr(v)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__repr__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Vector({0.x}, {0.y})'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("format")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),a("p",[t._v("Now it is possible to naturally use instances of the "),a("code",[t._v("Vector")]),t._v(" class in various expressions.")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[t._v("v "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Vector"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nu "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Vector"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nu "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" v "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Vector(3, 4)")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("u "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" v"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v('# "<3, 4>" (implicit string conversion)')]),t._v("\nu "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v(" v "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Vector(1, -4)")]),t._v("\nu "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" v "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# False")]),t._v("\nu "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" v "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" v "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" u "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# True")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("abs")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("u "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" v"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 5.0")]),t._v("\n\n")])])]),a("h2",{attrs:{id:"container-and-sequence-types"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#container-and-sequence-types"}},[t._v("#")]),t._v(" Container and sequence types")]),t._v(" "),a("p",[t._v("It is possible to emulate container types, which support accessing values by key or index.")]),t._v(" "),a("p",[t._v("Consider this naive implementation of a sparse list, which stores only its non-zero elements to conserve memory.")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("sparselist")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__init__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" size"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" size\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# l[index]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__getitem__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" index "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n index "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" index "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("raise")]),t._v(" IndexError"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("index"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("except")]),t._v(" KeyError"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# l[index] = value")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__setitem__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# del l[index]")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__delitem__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" index "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("del")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("index"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# value in l")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__contains__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.0")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("or")]),t._v(" value "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("values"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# len(l)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__len__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# for value in l: ...")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__iter__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("i"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" i "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("range")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("size"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# use xrange for python2")]),t._v("\n\n")])])]),a("p",[t._v("Then, we can use a "),a("code",[t._v("sparselist")]),t._v(" much like a regular "),a("code",[t._v("list")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[t._v("l "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" sparselist"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# list with 1 million elements")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" l "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# True")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" l "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# False")]),t._v("\n\nl"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12345")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" \n"),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" l "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# True")]),t._v("\nl"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("12345")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 10")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" v "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" l"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("pass")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 0, 0, 0, ... 10, 0, 0 ... 0")]),t._v("\n\n")])])]),a("h2",{attrs:{id:"callable-types"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#callable-types"}},[t._v("#")]),t._v(" Callable types")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("adder")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__init__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" first"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("first "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" first\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# a(...)")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__call__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" second"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("first "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" second\n\nadd2 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" adder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nadd2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 3")]),t._v("\nadd2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# 4")]),t._v("\n\n")])])]),a("h2",{attrs:{id:"handling-unimplemented-behaviour"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#handling-unimplemented-behaviour"}},[t._v("#")]),t._v(" Handling unimplemented behaviour")]),t._v(" "),a("p",[t._v("If your class doesn't implement a specific overloaded operator for the argument types provided, it should "),a("code",[t._v("return NotImplemented")]),t._v(" ("),a("strong",[t._v("note")]),t._v(" that this is a "),a("a",{attrs:{href:"https://docs.python.org/3/library/constants.html#NotImplemented",target:"_blank",rel:"noopener noreferrer"}},[t._v("special constant"),a("OutboundLink")],1),t._v(", not the same as "),a("code",[t._v("NotImplementedError")]),t._v("). This will allow Python to fall back to trying other methods to make the operation work:")]),t._v(" "),a("blockquote"),t._v(" "),a("p",[t._v("When `NotImplemented` is returned, the interpreter will then try the\nreflected operation on the other type, or some other fallback,\ndepending on the operator. If all attempted operations return\n`NotImplemented`, the interpreter will raise an appropriate exception.")]),t._v(" "),a("p",[t._v("For example, given "),a("code",[t._v("x + y")]),t._v(", if "),a("code",[t._v("x.__add__(y)")]),t._v(" returns unimplemented, "),a("code",[t._v("y.__radd__(x)")]),t._v(" is attempted instead.")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("NotAddable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("object")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__init__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" value\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__add__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" NotImplemented\n\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Addable")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("NotAddable"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("__add__")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" Addable"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("self"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" other"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n __radd__ "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" __add__\n\n")])])]),a("p",[t._v("As this is the "),a("strong",[t._v("reflected")]),t._v(" method we have to implement "),a("code",[t._v("__add__")]),t._v(" "),a("strong",[t._v("and")]),t._v(" "),a("code",[t._v("__radd__")]),t._v(" to get the expected behaviour in all cases; fortunately, as they are both doing the same thing in this simple example, we can take a shortcut.")]),t._v(" "),a("p",[t._v("In use:")]),t._v(" "),a("div",{staticClass:"language-py extra-class"},[a("pre",{pre:!0,attrs:{class:"language-py"}},[a("code",[a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" x "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" NotAddable"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" y "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Addable"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" x "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" x\nTraceback "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("most recent call last"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n File "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" line "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("module"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\nTypeError"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" unsupported operand "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("type")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("s"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'NotAddable'")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("and")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'NotAddable'")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" y "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("so"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Addable "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("object")]),t._v(" at "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0x1095974d0")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" z "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" x "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" z\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("so"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Addable "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("object")]),t._v(" at "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0x109597510")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" z"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value\n"),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]);