|
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