|
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