|
11 | 11 | """Docstring of the class."""
|
12 | 12 |
|
13 | 13 | def __init__(self) -> None:
|
14 |
| - """Docstring of the constructor __init__.""" |
| 14 | + """Docstring of the initializer __init__.""" |
15 | 15 | # initialize all attributes
|
16 | 16 | #: Meaning of attribute 1
|
17 | 17 | self.attribute_1: type hint = initial value
|
|
70 | 70 | A attribute is a variable that every single instance of the class has.
|
71 | 71 | In other words, we later want to be able to create one instance of \pythonil{Point} with the x\nobreakdashes-coordinate~5 and the y\nobreakdashes-coordinate~10 and then another instance with the x\nobreakdashes-coordinate~2 and the y\nobreakdashes-coordinate~7.
|
72 | 72 |
|
73 |
| -Therefore, \pythonil{Point} needs a constructor, i.e., a special method that creates these attributes. |
| 73 | +Therefore, \pythonil{Point} needs a initializer, i.e., a special method that creates these attributes. |
74 | 74 | This method is called~\pythonilIdx{\_\_init\_\_}.
|
75 | 75 | As said, every method of a class must have a parameter~\pythonilIdx{self}, which is the instance of the class (the object) upon which the method is called.
|
76 |
| -The constructor \pythonilIdx{\_\_init\_\_} is a special method, so it also has this parameter~\pythonilIdx{self}. |
| 76 | +The initializer \pythonilIdx{\_\_init\_\_} is a special method, so it also has this parameter~\pythonilIdx{self}. |
77 | 77 | Additionally, we demand that two parameters~\pythonil{x} and~\pythonil{y} be passed in when we create an instance of~\pythonil{Point}.
|
78 | 78 | We allow the values to be either \pythonils{int} or \pythonils{float}.%
|
79 | 79 | %
|
80 | 80 | \bestPractice{attributes}{%
|
81 |
| -Object attributes must only be created inside the constructor~\pythonilIdx{\_\_init\_\_}. % |
| 81 | +Object attributes must only be created inside the initializer~\pythonilIdx{\_\_init\_\_}. % |
82 | 82 | An initial value must immediately be assigned to each attribute.%
|
83 | 83 | }
|
84 | 84 | %
|
85 | 85 | We only want to allow \pythonils{Point} that have finite coordinates.
|
86 | 86 | As explained in the \cref{sec:exceptions} on \pythonilsIdx{Exception}, it is better to immediately signal errors if we encounter invalid data.
|
87 | 87 | So we want to sort out non-finite coordinates right when someone attempts to create the \pythonil{Point} object.
|
88 |
| -Thus, the first thing we do in the constructor is to use the \pythonilIdx{isfinite} function from the \pythonilIdx{math} module. |
| 88 | +Thus, the first thing we do in the initializer is to use the \pythonilIdx{isfinite} function from the \pythonilIdx{math} module. |
89 | 89 | If either \pythonil{x} or \pythonil{y} is not finite, then we raise\pythonIdx{raise} a \pythonilIdx{ValueError}.
|
90 | 90 | Otherwise, we set \pythonil{self.x: Final[int | float] = x} and \pythonil{self.y: Final[int | float] = y}.\footnote{%
|
91 | 91 | Strictly speaking, it could also make sense to check whether \pythonil{x} and \pythonil{y} are indeed either \pythonil{int} or \pythonil{float}. %
|
|
97 | 97 | In other words, we do not allow the coordinates of our \pythonils{Point} to be change after creation.%
|
98 | 98 | %
|
99 | 99 | \bestPractice{attributeTypeHint}{%
|
100 |
| -Every attribute of an object must be annotated with a \pgls{typeHint} and a documentation comment when created in the constructor~\pythonilIdx{\_\_init\_\_}. % |
| 100 | +Every attribute of an object must be annotated with a \pgls{typeHint} and a documentation comment when created in the initializer~\pythonilIdx{\_\_init\_\_}. % |
101 | 101 | \pglspl{typeHint} work as with normal variables, but the documentation is slightly different: %
|
102 | 102 | In the line \emph{above} the attribute initialization, a \emph{comment} starting with \pythonilIdx{\#: } must be written which explains the meaning of the attribute.%
|
103 | 103 | }%
|
|
140 | 140 | For \pythonil{p1}, this returns~\pythonil{True}.
|
141 | 141 |
|
142 | 142 | We now create a second instance, \pythonil{p2}, of the class \pythonil{Point}.
|
143 |
| -We assign \pythonil{7} to \pythonil{p2.x} and \pythonil{8} to \pythonil{p2.y} via the \pythonilIdx{\_\_init\_\_} constructor, which is automatically invoked when we write~\pythonil{Point(7, 8)}. |
| 143 | +We assign \pythonil{7} to \pythonil{p2.x} and \pythonil{8} to \pythonil{p2.y} via the \pythonilIdx{\_\_init\_\_} initializer, which is automatically invoked when we write~\pythonil{Point(7, 8)}. |
144 | 144 | We can again print the values of these attributes using an \pgls{fstring}.
|
145 | 145 | While \pythonil{isinstance(p2, Point)} is again \pythonil{True}, \pythonil{isinstance(5, Point)} returns \pythonil{False}.
|
146 | 146 |
|
|
165 | 165 | So the x\nobreakdashes-~and y\nobreakdashes-attributes of instances of \pythonil{Point} can actually be changed. %
|
166 | 166 | However, tools like \mypy\ will detect such mistakes and report them~\cite{PEP591}.%
|
167 | 167 | }
|
168 |
| -The x\nobreakdashes-~and y\nobreakdashes-attributes are initialized by the \pythonil{\_\_init\_\_} constructor. |
| 168 | +The x\nobreakdashes-~and y\nobreakdashes-attributes are initialized by the \pythonil{\_\_init\_\_} initializer. |
169 | 169 | They are marked with the \pgls{typeHint} \pythonilIdx{Final} and thus changing them is an error.
|
170 | 170 | In many cases, making objects immutable is a good design pattern.%
|
171 | 171 | %
|
|
333 | 333 | %
|
334 | 334 | This is going to be the interface for our new class~\pythonil{KahanSum}, which, in turn, is based on~\cite{K2006AGKBSA}.
|
335 | 335 |
|
336 |
| -In the constructor~\pythonilIdx{\_\_init\_\_}, we create the three attributes~\pythonil{__sum}, \pythonil{__cs}, and \pythonil{__ccs} and initialize them to~\pythonil{0}. |
| 336 | +In the initializer~\pythonilIdx{\_\_init\_\_}, we create the three attributes~\pythonil{__sum}, \pythonil{__cs}, and \pythonil{__ccs} and initialize them to~\pythonil{0}. |
337 | 337 | These names are directly taken from \cref{algo:kahanSum}.
|
338 | 338 | Notice the double leading underscores in front of the names.%
|
339 | 339 | %
|
|
0 commit comments