summaryrefslogtreecommitdiff
path: root/notebooks/python/python_oo.ipynb
diff options
context:
space:
mode:
Diffstat (limited to 'notebooks/python/python_oo.ipynb')
-rw-r--r--notebooks/python/python_oo.ipynb274
1 files changed, 274 insertions, 0 deletions
diff --git a/notebooks/python/python_oo.ipynb b/notebooks/python/python_oo.ipynb
new file mode 100644
index 0000000..0b33a09
--- /dev/null
+++ b/notebooks/python/python_oo.ipynb
@@ -0,0 +1,274 @@
1{
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "id": "2612fc97-1e84-4cc1-bd55-4cc58dbd5074",
6 "metadata": {},
7 "source": [
8 "# Introduction to object-oriented programming in Python\n",
9 "\n",
10 "Simeon Simeonov @ Statnett"
11 ]
12 },
13 {
14 "cell_type": "markdown",
15 "id": "84139fa9-733e-4871-a2f9-920f6e7c4911",
16 "metadata": {},
17 "source": [
18 "# Goals\n",
19 "\n",
20 "- present the Python programming language in a different way than [https://docs.python.org](https://docs.python.org)\n",
21 "\n",
22 "- avoid information overload\n",
23 "\n",
24 "- use examples and interaction rather than documents and slides\n",
25 "\n",
26 "\n",
27 "## Target audience\n",
28 "\n",
29 "- beginner Python programmers\n",
30 "\n",
31 "- analysts using Python as a tool"
32 ]
33 },
34 {
35 "cell_type": "markdown",
36 "id": "d6d3d0e7-c1d5-4119-940e-0f94ee7542ec",
37 "metadata": {},
38 "source": [
39 "# What is object-oriented programming?\n",
40 "\n",
41 "Object-oriented programming does **not** mean using an object-oriented programming language.\n",
42 "\n",
43 "It is rather a programming paradigm based on the concept of object, as well as on some general principles and best practices aiming at:\n",
44 "\n",
45 "- improving readability\n",
46 "\n",
47 "- improving re-usability\n",
48 "\n",
49 "- improving modularity\n",
50 "\n",
51 "- providing foundation for a more intuitive design"
52 ]
53 },
54 {
55 "cell_type": "markdown",
56 "id": "ad19da5c-3c21-4130-9225-d8f7cb2a7f40",
57 "metadata": {},
58 "source": [
59 "# General principles\n",
60 "\n",
61 "The following four concepts / principles are presented in most object-oriented programming books:\n",
62 "\n",
63 "- separate and hide \"private\" details from the outside world and / or child (inheriting) functionality (*encapsulation*) - supports *separation of concerns*\n",
64 "\n",
65 "- separate the interface from its implementation (*abstraction*)\n",
66 "\n",
67 "- inherit and extend / adapt existing functionality, through \"is-a\" relationship hierarchy (*inheritance*)\n",
68 "\n",
69 "- execute different code / functionality based on the object's place in the hierarchy (polymorphism)"
70 ]
71 },
72 {
73 "cell_type": "markdown",
74 "id": "22b2bf7e-764b-44c8-a9fd-83733319fc6e",
75 "metadata": {},
76 "source": [
77 "# Building blocks and definitions\n",
78 "\n",
79 "**Note:** \"Lacking universally accepted terminology to talk about classes, I will make occasional use of Smalltalk and C++ terms.\" - The Python tutorial [https://docs.python.org](https://docs.python.org)\n",
80 "\n",
81 "When talking about object-oriented programming, the following building blocks are involved:\n",
82 "\n",
83 "- class - a blueprint / template for creating objects\n",
84 "\n",
85 "- object - an instance of a class that may contain its own attributes as well as references to its class' attributes\n",
86 "\n",
87 "- attribute - variable, property, function defined in the class and present in its instances\n",
88 "\n",
89 "- class variable - attribute of which a single copy exists, regardless of how many instances of the class exist\n",
90 "\n",
91 "- object / instance variable - attribute for which each instantiated object of the class has a separate copy, or instance\n",
92 "\n",
93 "- method - member function - function that is an attribute"
94 ]
95 },
96 {
97 "cell_type": "markdown",
98 "id": "9e15c843-f65b-4bd3-a536-e0217b3947f8",
99 "metadata": {},
100 "source": [
101 "# The object-oriented world of Python\n",
102 "\n",
103 "Some additional concepts and definitions are introduced in Python, as well as in some other programming languages:\n",
104 "\n",
105 "- metaclass - a class whose instances are classes\n",
106 "\n",
107 "- property - attribute that provides a flexible mechanism to read, write, or compute the value of a \"private\" attribute\n",
108 "\n",
109 "- type - old C object-oriented term, now (in Python 3) considered to be the same as class\n",
110 "\n",
111 "As is true for modules, classes partake of the dynamic nature of Python: they are created at runtime, and can be modified further after creation.\n",
112 "\n",
113 "Each object in Python has an ID - an integer which is guaranteed to be unique and constant for this object during its lifetime.\n",
114 "Two objects with non-overlapping lifetimes may have the same *id()* value. In *CPython* this is the address of the object in memory.\n",
115 "\n",
116 "Python has automatic memory management using reference counting. When an object no longer has\n",
117 "any references, the garbage collector kicks inn and removes the object from memory."
118 ]
119 },
120 {
121 "cell_type": "markdown",
122 "id": "d647b1ad-948d-495d-bb30-15761b806354",
123 "metadata": {},
124 "source": [
125 "# Example1\n",
126 "\n",
127 "We will create and extend classes for representing points and vectors in 2D space"
128 ]
129 },
130 {
131 "cell_type": "code",
132 "execution_count": 7,
133 "id": "391e816e-c53b-454b-9e9f-3587234f1fea",
134 "metadata": {},
135 "outputs": [
136 {
137 "name": "stdout",
138 "output_type": "stream",
139 "text": [
140 "2:8\n",
141 "2:8\n",
142 "2\n",
143 "2\n"
144 ]
145 },
146 {
147 "ename": "AttributeError",
148 "evalue": "'Point' object has no attribute '__y'",
149 "output_type": "error",
150 "traceback": [
151 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
152 "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
153 "Cell \u001b[0;32mIn [7], line 69\u001b[0m\n\u001b[1;32m 66\u001b[0m \u001b[38;5;66;03m# we \"should not\" be accessing private and protected attributes directly\u001b[39;00m\n\u001b[1;32m 67\u001b[0m \u001b[38;5;28mprint\u001b[39m(my_first_point\u001b[38;5;241m.\u001b[39m_x)\n\u001b[0;32m---> 69\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mmy_first_point\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__y\u001b[49m)\n",
154 "\u001b[0;31mAttributeError\u001b[0m: 'Point' object has no attribute '__y'"
155 ]
156 }
157 ],
158 "source": [
159 "class Point:\n",
160 " \"\"\"Basic class for representing points in 2D space\"\"\"\n",
161 "\n",
162 " def __init__(self, x: int, y: int):\n",
163 " \"\"\"\n",
164 " Called after the instance has been created (by __new__()), but before\n",
165 " it is returned to the caller. The arguments are those passed to the\n",
166 " class constructor expression.\n",
167 " \n",
168 " If a base class has an __init__() method, the derived class’s\n",
169 " __init__() method, if any, must explicitly call it to ensure proper\n",
170 " initialization of the base class part of the instance;\n",
171 " for example: super().__init__([args...]).\n",
172 " \"\"\"\n",
173 " self._x = x # _ indicates \"protected\" attribute\n",
174 " self.__y = y # not a typo: __ indicates \"private\" attribute\n",
175 "\n",
176 " def __repr__(self):\n",
177 " \"\"\"\n",
178 " Called by the repr() built-in function to compute the “official”\n",
179 " string representation of an object. If at all possible, this should\n",
180 " look like a valid Python expression that could be used to recreate an\n",
181 " object with the same value (given an appropriate environment). If this\n",
182 " is not possible, a string of the form <...some useful description...>\n",
183 " should be returned. The return value must be a string object.\n",
184 " \n",
185 " If a class defines __repr__() but not __str__(), then __repr__() is\n",
186 " also used when an “informal” string representation of instances of\n",
187 " that class is required. This is typically used for debugging, so it is\n",
188 " important that the representation is information-rich and unambiguous.\n",
189 " \"\"\"\n",
190 " return f\"<Point(x={self._x!r}, y={self.__y!r})>\"\n",
191 "\n",
192 " def __str__(self):\n",
193 " \"\"\"\n",
194 " Called by str(object) and the built-in functions format() and print()\n",
195 " to compute the “informal” or nicely printable string representation of\n",
196 " an object. The return value must be a string object.\n",
197 "\n",
198 " This method differs from object.__repr__() in that there is no\n",
199 " expectation that __str__() return a valid Python expression: a more\n",
200 " convenient or concise representation can be used.\n",
201 "\n",
202 " The default implementation defined by the built-in type object calls\n",
203 " object.__repr__().\n",
204 " \"\"\"\n",
205 " return f\"{self._x}:{self.__y}\"\n",
206 "\n",
207 " @property\n",
208 " def x(self) -> int:\n",
209 " \"\"\"getter property x\"\"\"\n",
210 " return self._x\n",
211 "\n",
212 " @property\n",
213 " def y(self) -> int:\n",
214 " \"\"\"getter property y\"\"\"\n",
215 " return self.__y\n",
216 "\n",
217 "\n",
218 "my_first_point = Point(2, 8)\n",
219 "\n",
220 "print(f\"{my_first_point}\")\n",
221 "print(f\"{my_first_point}\")\n",
222 "print(my_first_point.x)\n",
223 "\n",
224 "# we \"should not\" be accessing private and protected attributes directly\n",
225 "print(my_first_point._x)\n",
226 "\n",
227 "print(my_first_point.__y) # will not work\n",
228 "# Out: AttributeError: 'Point' object has no attribute '__y'\n",
229 "\n",
230 "# will work, but should not be used by a sane programmer:\n",
231 "# print(my_first_point._Point__y)"
232 ]
233 },
234 {
235 "cell_type": "code",
236 "execution_count": null,
237 "id": "e82feefb-025d-4cbb-a8ac-ddc3cc01269c",
238 "metadata": {},
239 "outputs": [],
240 "source": [
241 "class Vector:\n",
242 " \"\"\"Basic class for representing vectors in 2D space\"\"\"\n",
243 "\n",
244 " def __init__(self, start: Point, end: Point):\n",
245 " self._start = start\n",
246 " self._end = end\n",
247 "\n",
248 " def __str__(self):\n",
249 " return f\"{self._start} -> {self._end}\"\n"
250 ]
251 }
252 ],
253 "metadata": {
254 "kernelspec": {
255 "display_name": "Python 3 (ipykernel)",
256 "language": "python",
257 "name": "python3"
258 },
259 "language_info": {
260 "codemirror_mode": {
261 "name": "ipython",
262 "version": 3
263 },
264 "file_extension": ".py",
265 "mimetype": "text/x-python",
266 "name": "python",
267 "nbconvert_exporter": "python",
268 "pygments_lexer": "ipython3",
269 "version": "3.8.10"
270 }
271 },
272 "nbformat": 4,
273 "nbformat_minor": 5
274}