diff options
| author | Simeon Simeonov | 2022-10-28 13:43:55 +0200 |
|---|---|---|
| committer | Simeon Simeonov | 2022-10-28 13:43:55 +0200 |
| commit | a5ad1fd2ab1abba086148d1d676426af3d9a58a9 (patch) | |
| tree | cbd6c6d83c105409efcee08a4610bfea9856f5bf | |
| parent | e4c798c37d0ee961d44a1e8316617374e2053016 (diff) | |
Update python_oo.ipynb
| -rw-r--r-- | notebooks/python/python_oo.ipynb | 146 |
1 files changed, 121 insertions, 25 deletions
diff --git a/notebooks/python/python_oo.ipynb b/notebooks/python/python_oo.ipynb index 2440efb..df5907b 100644 --- a/notebooks/python/python_oo.ipynb +++ b/notebooks/python/python_oo.ipynb | |||
| @@ -208,7 +208,7 @@ | |||
| 208 | }, | 208 | }, |
| 209 | { | 209 | { |
| 210 | "cell_type": "code", | 210 | "cell_type": "code", |
| 211 | "execution_count": 287, | 211 | "execution_count": 70, |
| 212 | "id": "391e816e-c53b-454b-9e9f-3587234f1fea", | 212 | "id": "391e816e-c53b-454b-9e9f-3587234f1fea", |
| 213 | "metadata": {}, | 213 | "metadata": {}, |
| 214 | "outputs": [ | 214 | "outputs": [ |
| @@ -306,7 +306,7 @@ | |||
| 306 | }, | 306 | }, |
| 307 | { | 307 | { |
| 308 | "cell_type": "code", | 308 | "cell_type": "code", |
| 309 | "execution_count": 288, | 309 | "execution_count": 71, |
| 310 | "id": "e82feefb-025d-4cbb-a8ac-ddc3cc01269c", | 310 | "id": "e82feefb-025d-4cbb-a8ac-ddc3cc01269c", |
| 311 | "metadata": {}, | 311 | "metadata": {}, |
| 312 | "outputs": [ | 312 | "outputs": [ |
| @@ -389,7 +389,7 @@ | |||
| 389 | }, | 389 | }, |
| 390 | { | 390 | { |
| 391 | "cell_type": "code", | 391 | "cell_type": "code", |
| 392 | "execution_count": 289, | 392 | "execution_count": 72, |
| 393 | "id": "71a90ec6-3cc0-441e-a866-c2c2b9984559", | 393 | "id": "71a90ec6-3cc0-441e-a866-c2c2b9984559", |
| 394 | "metadata": {}, | 394 | "metadata": {}, |
| 395 | "outputs": [ | 395 | "outputs": [ |
| @@ -503,7 +503,7 @@ | |||
| 503 | }, | 503 | }, |
| 504 | { | 504 | { |
| 505 | "cell_type": "code", | 505 | "cell_type": "code", |
| 506 | "execution_count": 290, | 506 | "execution_count": 73, |
| 507 | "id": "a4d2735d-d167-4f43-ad55-cb3d13ece2dc", | 507 | "id": "a4d2735d-d167-4f43-ad55-cb3d13ece2dc", |
| 508 | "metadata": {}, | 508 | "metadata": {}, |
| 509 | "outputs": [ | 509 | "outputs": [ |
| @@ -546,7 +546,7 @@ | |||
| 546 | }, | 546 | }, |
| 547 | { | 547 | { |
| 548 | "cell_type": "code", | 548 | "cell_type": "code", |
| 549 | "execution_count": 291, | 549 | "execution_count": 74, |
| 550 | "id": "a6ead5e6-e987-4bda-bf48-30f91877278d", | 550 | "id": "a6ead5e6-e987-4bda-bf48-30f91877278d", |
| 551 | "metadata": {}, | 551 | "metadata": {}, |
| 552 | "outputs": [ | 552 | "outputs": [ |
| @@ -605,7 +605,7 @@ | |||
| 605 | }, | 605 | }, |
| 606 | { | 606 | { |
| 607 | "cell_type": "code", | 607 | "cell_type": "code", |
| 608 | "execution_count": 292, | 608 | "execution_count": 75, |
| 609 | "id": "11f6a3fb-64d7-40a9-a130-27548ec4b802", | 609 | "id": "11f6a3fb-64d7-40a9-a130-27548ec4b802", |
| 610 | "metadata": {}, | 610 | "metadata": {}, |
| 611 | "outputs": [ | 611 | "outputs": [ |
| @@ -683,7 +683,7 @@ | |||
| 683 | }, | 683 | }, |
| 684 | { | 684 | { |
| 685 | "cell_type": "code", | 685 | "cell_type": "code", |
| 686 | "execution_count": 293, | 686 | "execution_count": 76, |
| 687 | "id": "c345a69f-02da-40e7-bb37-c0511b6af096", | 687 | "id": "c345a69f-02da-40e7-bb37-c0511b6af096", |
| 688 | "metadata": {}, | 688 | "metadata": {}, |
| 689 | "outputs": [ | 689 | "outputs": [ |
| @@ -774,7 +774,7 @@ | |||
| 774 | }, | 774 | }, |
| 775 | { | 775 | { |
| 776 | "cell_type": "code", | 776 | "cell_type": "code", |
| 777 | "execution_count": 294, | 777 | "execution_count": 77, |
| 778 | "id": "44d47e1c-1a06-4577-8db6-6ec78ce5cef8", | 778 | "id": "44d47e1c-1a06-4577-8db6-6ec78ce5cef8", |
| 779 | "metadata": {}, | 779 | "metadata": {}, |
| 780 | "outputs": [ | 780 | "outputs": [ |
| @@ -815,7 +815,8 @@ | |||
| 815 | " | \n", | 815 | " | \n", |
| 816 | " | weight\n", | 816 | " | weight\n", |
| 817 | " | getter property weight\n", | 817 | " | getter property weight\n", |
| 818 | "\n" | 818 | "\n", |
| 819 | "(<class '__main__.TigerShark'>, <class '__main__.Fish'>, <class '__main__.Animal'>, <class 'object'>)\n" | ||
| 819 | ] | 820 | ] |
| 820 | } | 821 | } |
| 821 | ], | 822 | ], |
| @@ -903,7 +904,8 @@ | |||
| 903 | "cow1 = Cow(350)\n", | 904 | "cow1 = Cow(350)\n", |
| 904 | "cow1.make_a_sound()\n", | 905 | "cow1.make_a_sound()\n", |
| 905 | "tiger_shark1 = TigerShark(80)\n", | 906 | "tiger_shark1 = TigerShark(80)\n", |
| 906 | "help(TigerShark)" | 907 | "help(TigerShark)\n", |
| 908 | "print(TigerShark.__mro__) # more elegant will be to use the inspect module: inspect.getmro(TigerShark)" | ||
| 907 | ] | 909 | ] |
| 908 | }, | 910 | }, |
| 909 | { | 911 | { |
| @@ -917,7 +919,7 @@ | |||
| 917 | "\n", | 919 | "\n", |
| 918 | "- how do we handle the growing amount of params we have to send to `super()`?\n", | 920 | "- how do we handle the growing amount of params we have to send to `super()`?\n", |
| 919 | "\n", | 921 | "\n", |
| 920 | "- how do insert functionality that does not necessarily follow the structure of our hierarchy. F.i predator functionality?\n", | 922 | "- how to insert functionality that does not necessarily follow the structure of our hierarchy. F.i predator functionality?\n", |
| 921 | "\n", | 923 | "\n", |
| 922 | "\n", | 924 | "\n", |
| 923 | "## Possible solutions\n", | 925 | "## Possible solutions\n", |
| @@ -945,18 +947,8 @@ | |||
| 945 | ] | 947 | ] |
| 946 | }, | 948 | }, |
| 947 | { | 949 | { |
| 948 | "cell_type": "markdown", | ||
| 949 | "id": "35b3a8eb-e7b0-4181-822f-923a74a7ab27", | ||
| 950 | "metadata": {}, | ||
| 951 | "source": [ | ||
| 952 | "# Example 3\n", | ||
| 953 | "\n", | ||
| 954 | "Demonstrates the use of mixins." | ||
| 955 | ] | ||
| 956 | }, | ||
| 957 | { | ||
| 958 | "cell_type": "code", | 950 | "cell_type": "code", |
| 959 | "execution_count": 295, | 951 | "execution_count": 78, |
| 960 | "id": "e6076925-75f0-456c-aed5-7db0a24a67a1", | 952 | "id": "e6076925-75f0-456c-aed5-7db0a24a67a1", |
| 961 | "metadata": {}, | 953 | "metadata": {}, |
| 962 | "outputs": [ | 954 | "outputs": [ |
| @@ -1048,12 +1040,20 @@ | |||
| 1048 | "In other words, you don't get to choose who your `super()` is going to call, your children get to choose. \n", | 1040 | "In other words, you don't get to choose who your `super()` is going to call, your children get to choose. \n", |
| 1049 | "Single inheritance is just a special case and simplification of the general rule.\n", | 1041 | "Single inheritance is just a special case and simplification of the general rule.\n", |
| 1050 | "\n", | 1042 | "\n", |
| 1051 | "Python>=2.3 uses the [C3 Method Resolution Order (MRO)](https://www.python.org/download/releases/2.3/mro/), replacing the old *depth first and then left to right* in Python<=2.2." | 1043 | "Python>=2.3 uses the [C3 Method Resolution Order (MRO)](https://www.python.org/download/releases/2.3/mro/), replacing the old *depth first and then left to right* in Python<=2.2.\n", |
| 1044 | "\n", | ||
| 1045 | "The *MRO* is the set of rules that construct the linearization. In the Python literature, the idiom \"the MRO of C\" is also used as a synonymous for the linearization of the class C.\n", | ||
| 1046 | "\n", | ||
| 1047 | "MRO is monotonic when the following is true: if C1 precedes C2 in the linearization of C, then C1 precedes C2 in the linearization of any subclass of C.\n", | ||
| 1048 | "\n", | ||
| 1049 | "Not all classes admit a linearization. There are cases, in complicated hierarchies, where it is not possible to derive a class such that its linearization respects all the desired properties. \n", | ||
| 1050 | "`TypeError: Cannot create a consistent method resolution order (MRO) for bases X, Y` is raised then.\n", | ||
| 1051 | "\n" | ||
| 1052 | ] | 1052 | ] |
| 1053 | }, | 1053 | }, |
| 1054 | { | 1054 | { |
| 1055 | "cell_type": "code", | 1055 | "cell_type": "code", |
| 1056 | "execution_count": 296, | 1056 | "execution_count": 79, |
| 1057 | "id": "cf79617a-95d2-48f2-be66-fa1fa34e4e04", | 1057 | "id": "cf79617a-95d2-48f2-be66-fa1fa34e4e04", |
| 1058 | "metadata": {}, | 1058 | "metadata": {}, |
| 1059 | "outputs": [ | 1059 | "outputs": [ |
| @@ -1106,6 +1106,98 @@ | |||
| 1106 | ] | 1106 | ] |
| 1107 | }, | 1107 | }, |
| 1108 | { | 1108 | { |
| 1109 | "cell_type": "code", | ||
| 1110 | "execution_count": 80, | ||
| 1111 | "id": "95a1d0cc-0006-4ddc-b08d-d0b8b02acfba", | ||
| 1112 | "metadata": {}, | ||
| 1113 | "outputs": [ | ||
| 1114 | { | ||
| 1115 | "name": "stdout", | ||
| 1116 | "output_type": "stream", | ||
| 1117 | "text": [ | ||
| 1118 | "Getting data using a proprietary driver, from a proprietary high tech & mega secured cluster while being charged 100USD per MB\n", | ||
| 1119 | "Extracting production plans from data\n", | ||
| 1120 | "some magic is happening here...\n", | ||
| 1121 | "{}\n" | ||
| 1122 | ] | ||
| 1123 | } | ||
| 1124 | ], | ||
| 1125 | "source": [ | ||
| 1126 | "# Real multiple inheritance\n", | ||
| 1127 | "\n", | ||
| 1128 | "# Inspired by Raymond Hettinger - \"Super considered super!\" - PyCon 2015\n", | ||
| 1129 | "import json\n", | ||
| 1130 | "\n", | ||
| 1131 | "\n", | ||
| 1132 | "class ConnectionManager:\n", | ||
| 1133 | " \"\"\"Handles connection and extraction of raw data\"\"\"\n", | ||
| 1134 | "\n", | ||
| 1135 | " def get_data(self, *args, **kwargs):\n", | ||
| 1136 | " \"\"\"difficult and expensive to test functionality here\"\"\"\n", | ||
| 1137 | " print(\n", | ||
| 1138 | " \"Getting data using a proprietary driver, from a proprietary high \"\n", | ||
| 1139 | " \"tech & mega secured cluster while being charged 100USD per MB\"\n", | ||
| 1140 | " )\n", | ||
| 1141 | " \n", | ||
| 1142 | " def extract_production_plans(self, *args, **kwargs):\n", | ||
| 1143 | " print(\"Extracting production plans from data\")\n", | ||
| 1144 | "\n", | ||
| 1145 | "\n", | ||
| 1146 | "class CoolTSPreprocessor(ConnectionManager):\n", | ||
| 1147 | " \"\"\"Produces JSON content for production plans\"\"\"\n", | ||
| 1148 | " \n", | ||
| 1149 | " def to_json(self, **kwargs):\n", | ||
| 1150 | " # super().get_data(**kwargs)\n", | ||
| 1151 | " self.get_data(**kwargs)\n", | ||
| 1152 | " prod_plans = self.extract_production_plans(**kwargs)\n", | ||
| 1153 | " return json.dumps(self.__do_some_magic(prod_plans), indent=kwargs.get(\"indent\", 2))\n", | ||
| 1154 | " \n", | ||
| 1155 | " def __do_some_magic(self, prod_plans):\n", | ||
| 1156 | " processed_plans = {}\n", | ||
| 1157 | " print(\"some magic is happening here...\")\n", | ||
| 1158 | " return processed_plans\n", | ||
| 1159 | "\n", | ||
| 1160 | "\n", | ||
| 1161 | "class MockConnectionManager(ConnectionManager):\n", | ||
| 1162 | " \"\"\"\n", | ||
| 1163 | " Mock connection manager using a static data without really connecting to a real cluster\n", | ||
| 1164 | " \"\"\"\n", | ||
| 1165 | "\n", | ||
| 1166 | " def get_data(self, *args, **kwargs):\n", | ||
| 1167 | " print(\"Using mock data\")\n", | ||
| 1168 | "\n", | ||
| 1169 | "\n", | ||
| 1170 | "cool_ts_proprocessor = CoolTSPreprocessor()\n", | ||
| 1171 | "print(cool_ts_proprocessor.to_json(indent=4))" | ||
| 1172 | ] | ||
| 1173 | }, | ||
| 1174 | { | ||
| 1175 | "cell_type": "code", | ||
| 1176 | "execution_count": 81, | ||
| 1177 | "id": "38066107-0190-4383-ba14-a4e9cd454a9c", | ||
| 1178 | "metadata": {}, | ||
| 1179 | "outputs": [ | ||
| 1180 | { | ||
| 1181 | "name": "stdout", | ||
| 1182 | "output_type": "stream", | ||
| 1183 | "text": [ | ||
| 1184 | "Using mock data\n", | ||
| 1185 | "Extracting production plans from data\n", | ||
| 1186 | "some magic is happening here...\n", | ||
| 1187 | "(<class '__main__.MockedButStillCoolTSPreprocessor'>, <class '__main__.CoolTSPreprocessor'>, <class '__main__.MockConnectionManager'>, <class '__main__.ConnectionManager'>, <class 'object'>)\n" | ||
| 1188 | ] | ||
| 1189 | } | ||
| 1190 | ], | ||
| 1191 | "source": [ | ||
| 1192 | "class MockedButStillCoolTSPreprocessor(CoolTSPreprocessor, MockConnectionManager):\n", | ||
| 1193 | " pass\n", | ||
| 1194 | "\n", | ||
| 1195 | "mocked_but_still_cool_ts_preprocessor = MockedButStillCoolTSPreprocessor()\n", | ||
| 1196 | "mocked_but_still_cool_ts_preprocessor.to_json(indent=4)\n", | ||
| 1197 | "print(MockedButStillCoolTSPreprocessor.__mro__)" | ||
| 1198 | ] | ||
| 1199 | }, | ||
| 1200 | { | ||
| 1109 | "cell_type": "markdown", | 1201 | "cell_type": "markdown", |
| 1110 | "id": "540de317-ba77-4f5c-97ba-f1c0bec071fb", | 1202 | "id": "540de317-ba77-4f5c-97ba-f1c0bec071fb", |
| 1111 | "metadata": {}, | 1203 | "metadata": {}, |
| @@ -1124,7 +1216,11 @@ | |||
| 1124 | "\n", | 1216 | "\n", |
| 1125 | " - `__hash__`\n", | 1217 | " - `__hash__`\n", |
| 1126 | " \n", | 1218 | " \n", |
| 1127 | " - ...\n" | 1219 | " - ...\n", |
| 1220 | "\n", | ||
| 1221 | "- [Raymond Hettinger - Super considered super! - PyCon 2015](https://www.youtube.com/watch?v=EiOglTERPEo)\n", | ||
| 1222 | "\n", | ||
| 1223 | "- [C3 Method Resolution Order (MRO)](https://www.python.org/download/releases/2.3/mro/) - for the real enthusiasts" | ||
| 1128 | ] | 1224 | ] |
| 1129 | } | 1225 | } |
| 1130 | ], | 1226 | ], |
