|
1 | 1 | \hsection{Dunder Methods}% |
2 | 2 | % |
3 | | -In \python, \emph{everything is an object}~\cite{PSF2024OVAT,J2022PPEIAOSCD}. |
| 3 | +In \python, \emph{everything is an object}~\cite{PSF:P3D:TPLR:OVAT,J2022PPEIAOSCD}. |
4 | 4 | Functions, modules, classes, datatypes, values of simple datatypes, and so on -- all are objects. |
5 | 5 | Many of these objects have special functionality. |
6 | 6 | For example, we can add, multiply, and divide numerical objects. |
|
143 | 143 | If so, it will return \pythonil{True} if and only if the \pythonil{x} and \pythonil{y} coordinate of the \pythonil{other} point are the same as of the point \pythonil{self}. |
144 | 144 | Otherwise, it will return the constant \pythonilIdx{NotImplemented}:% |
145 | 145 | % |
146 | | -\cquotation{PSF2024BIC}{% |
| 146 | +\cquotation{PSF:P3D:TPSL:BIC}{% |
147 | 147 | A special value which should be returned by the binary special methods [\dots] to indicate that the operation is not implemented with respect to the other type\dots\medskip\\\strut\hspace{1cm}\strut% |
148 | 148 | \emph{Note:}~When a binary (or in-place) method returns \pythonilIdx{NotImplemented} the interpreter will try the reflected operation on the other type (or some other fallback, depending on the operator). % |
149 | 149 | If all attempts return \pythonilIdx{NotImplemented}, the interpreter will raise an appropriate exception. % |
|
186 | 186 | % |
187 | 187 | \end{itemize}% |
188 | 188 | % |
189 | | -For these two methods, it must hold that~\cite{PSF2024OH}% |
| 189 | +For these two methods, it must hold that~\cite{PSF:P3D:TPLR:OH}% |
190 | 190 | % |
191 | 191 | \begin{equation}% |
192 | 192 | \pythonil{a.\_\_eq\_\_(b)} \Rightarrow \pythonil{a.\_\_hash\_\_()} = \pythonil{b.\_\_hash\_\_()}% |
193 | 193 | \label{eq:eqAndHash1}% |
194 | 194 | \end{equation}% |
195 | 195 | % |
196 | | -This is equivalent~\cite{PSF2024BIE,PSF2024OH} to:% |
| 196 | +This is equivalent~\cite{PSF:P3D:TPSL:BIE,PSF:P3D:TPLR:OH} to:% |
197 | 197 | % |
198 | 198 | \begin{equation}% |
199 | 199 | \pythonil{a == b} \Rightarrow \pythonil{hash(a)} = \pythonil{hash(b)}% |
|
253 | 253 | In \cref{lst:dunder:point_with_hash}, we modify the \pythonil{Point} class from \cref{lst:dunder:point_with_dunder}. |
254 | 254 | We retain the implementation of~\dunder{eq} and add the method~\dunder{hash}.% |
255 | 255 | % |
256 | | -\cquotation{PSF2024OH}{{\dots}The \pythonil{\_\_hash\_\_()}\pythonIdx{\_\_hash\_\_}\pythonIdx{dunder!\_\_hash\_\_} method should return an integer. % |
| 256 | +\cquotation{PSF:P3D:TPLR:OH}{{\dots}The \pythonil{\_\_hash\_\_()}\pythonIdx{\_\_hash\_\_}\pythonIdx{dunder!\_\_hash\_\_} method should return an integer. % |
257 | 257 | The only required property is that objects which compare equal have the same hash value; % |
258 | 258 | it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a \pythonil{tuple} and hashing the tuple.}% |
259 | 259 | % |
260 | 260 | \bestPractice{hash}{% |
261 | | -For implementing \dunder{eq} and \dunder{hash}, the following rules hold~\cite{PSF2024OH}:% |
| 261 | +For implementing \dunder{eq} and \dunder{hash}, the following rules hold~\cite{PSF:P3D:TPLR:OH}:% |
262 | 262 | \sloppy% |
263 | 263 | \begin{itemize}\sloppy% |
264 | 264 | % |
|
301 | 301 | Actually, I secretly planned to use this as a very tricky example for learning how to use the debugger{\dots} |
302 | 302 | Alas, the developers of \python\ have already solved this:% |
303 | 303 | % |
304 | | -\cquotation{PSF2024BIF}{Numeric values that compare equal have the same \pythonilIdx{hash} value (even if they are of different types, as is the case for~\pythonil{1} and~\pythonil{1.0}).}% |
| 304 | +\cquotation{PSF:P3D:TPSL:BIF}{Numeric values that compare equal have the same \pythonilIdx{hash} value (even if they are of different types, as is the case for~\pythonil{1} and~\pythonil{1.0}).}% |
305 | 305 | % |
306 | 306 | Therefore, we can indeed implement \dunder{hash} with a single line of code in~\cref{sec:hashDunder}. |
307 | 307 | And I will later find another example on how the debugger can be used to spot errors in code.% |
|
340 | 340 | We implement the basic arithmetic operations for a class~\pythonil{Fraction} that represents fractions~$q\in\rationalNumbers$, i.e., it holds that~$q=\frac{a}{b}$ with~$a,b\in\integerNumbers$ and~$b\neq0$.\footnote{ |
341 | 341 | \python\ already has such a type built-in. % |
342 | 342 | Our goal here is to explore dunder methods, so we make our own class instead. % |
343 | | -In any actual application, you would use the more efficient class \pythonilIdx{Fraction} from the module~\pythonilIdx{fractions}~\cite{PSF2024FRN}.% |
| 343 | +In any actual application, you would use the more efficient class \pythonilIdx{Fraction} from the module~\pythonilIdx{fractions}~\cite{PSF:P3D:TPSL:FRN}.% |
344 | 344 | } |
345 | 345 | In other words, we want to pour primary school mathematics into a new numerical type. |
346 | 346 | To refresh our memory, $a$~is called the \pgls{numerator} and $b$~is called the \pgls{denominator} of the fraction~$\frac{a}{b}$. |
|
1385 | 1385 | The \pythonilIdx{\_\_exit\_\_}\pythonIdx{dunder!\_\_exit\_\_} method looks a bit different from \pythonilIdx{\_\_enter\_\_}\pythonIdx{dunder!\_\_enter\_\_}. |
1386 | 1386 | First, it also gets three parameters: the exception type~\pythonil{exc_type}, the exception value~\pythonil{exc_value}, and the stack~\pythonil{traceback}. |
1387 | 1387 | These parameters are filled with the information about any \pythonilIdx{Exception} raised within the \pythonilIdx{with}~body. |
1388 | | -Otherwise, they will be~\pythonil{None}~\cite{PSF2024WSCM}. |
| 1388 | +Otherwise, they will be~\pythonil{None}~\cite{PSF:P3D:TPLR:WSCM}. |
1389 | 1389 | We here just define a single parameter~\pythonil{*exc}. |
1390 | 1390 | This syntax tells \python\ to capture all positional arguments into a single tuple. |
1391 | 1391 | Since we do not care about exceptions here, we just write this to safe space, honestly, because I do not want to write three lines of \pgls{docstring} where one suffices. |
|
0 commit comments