WEBVTT

00:00:00.000 --> 00:00:04.780
Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Python-Podcast in der Episode Nummer 33.

00:00:05.080 --> 00:00:08.740
Die hatten wir letztes Mal ausgelesen. Deswegen müssen wir die Episode Nummer jetzt ergänzen.

00:00:09.420 --> 00:00:12.420
Ja, was machen wir heute? Wir wollen heute über Imports reden. Hi, Jochen.

00:00:12.980 --> 00:00:14.300
Ja, li, hallo, willkommen Dominik.

00:00:14.900 --> 00:00:15.420
Hi, Johannes.

00:00:15.720 --> 00:00:16.880
Ja, hallo, ich bin auch mal wieder da.

00:00:17.340 --> 00:00:18.160
Ja, wir kennen uns ja alle schon.

00:00:18.680 --> 00:00:20.940
Ja, also über das Python-Importsystem wollen wir heute sprechen.

00:00:21.060 --> 00:00:23.220
Vielleicht ein paar kleine News vorweg, wie wir das gerne tun.

00:00:23.340 --> 00:00:25.100
Und dann gehen wir so ein bisschen in die Details.

00:00:25.900 --> 00:00:26.800
Habt ihr News mitgebracht?

00:00:26.800 --> 00:00:29.040
Ja, also die einzigen

00:00:29.040 --> 00:00:30.840
News, die ich habe, ist, dass Apple sich gerade den

00:00:30.840 --> 00:00:32.960
größten PR-Unfug aller

00:00:32.960 --> 00:00:34.980
Zeiten einholt. Aber

00:00:34.980 --> 00:00:36.960
da ich kein Apple-Gerät habe, geht es

00:00:36.960 --> 00:00:38.780
ein kleines bisschen mehr. Das Problem habe ich auch nicht.

00:00:39.720 --> 00:00:40.580
Jochen, erzähl du doch mal.

00:00:42.340 --> 00:00:43.020
Ja, nee,

00:00:43.060 --> 00:00:44.860
tatsächlich ist es PR-technisch, würde ich

00:00:44.860 --> 00:00:47.080
sagen, auch aus meiner Perspektive ein großer Unfall.

00:00:47.680 --> 00:00:48.660
Wenn man sich jetzt anguckt, was sie

00:00:48.660 --> 00:00:50.200
technisch tun, ist es nicht so furchtbar schlimm.

00:00:50.200 --> 00:00:52.920
Was ist denn überhaupt passiert? Vielleicht jetzt mal so die Story.

00:00:54.560 --> 00:00:55.240
Sie haben irgendwie

00:00:55.240 --> 00:00:56.500
War das eine Pressemeldung?

00:00:57.020 --> 00:00:59.920
Es war eine Pressemeldung und es war eine technische Meldung, glaube ich,

00:01:00.320 --> 00:01:01.560
dass sie jetzt CSAM

00:01:01.560 --> 00:01:03.900
angemacht haben, Contact Content Scanning

00:01:03.900 --> 00:01:05.320
and

00:01:05.320 --> 00:01:07.680
keine Ahnung, was es bedeutet.

00:01:09.040 --> 00:01:09.760
Ja, jedenfalls

00:01:09.760 --> 00:01:11.540
wollen sie, jedenfalls will

00:01:11.540 --> 00:01:13.540
Apple jetzt in die Fotos reingucken und

00:01:13.540 --> 00:01:15.540
verbotene Inhalte finden.

00:01:16.440 --> 00:01:17.540
Ja, das ist natürlich

00:01:17.540 --> 00:01:19.500
so ein bisschen, das, ja.

00:01:19.700 --> 00:01:20.880
Mit modernster Technologie.

00:01:20.880 --> 00:01:22.560
Ja, zum Glück

00:01:22.560 --> 00:01:24.820
ist es nicht das Schlimme.

00:01:25.240 --> 00:01:27.340
und Technologie, was man halt auch nehmen könnte,

00:01:27.500 --> 00:01:29.600
sondern es ist halt irgendwas total Billiges,

00:01:30.000 --> 00:01:31.460
einfach nur Hashes in Bildern angucken.

00:01:31.540 --> 00:01:33.480
Also im Grunde nur gucken, ist das ein

00:01:33.480 --> 00:01:35.320
Bild, das auf irgendeiner Liste draufsteht

00:01:35.320 --> 00:01:36.880
von verbotenen Bildern.

00:01:37.380 --> 00:01:39.040
Ja, aber haben die nicht auch gesagt, dass sie so

00:01:39.040 --> 00:01:41.240
neuronale Netze drüberlaufen lassen

00:01:41.240 --> 00:01:42.440
und dann Sachen erkennen wollen?

00:01:43.400 --> 00:01:44.860
Oder ist das erst der nächste Schritt?

00:01:45.220 --> 00:01:47.120
Ja, genau, das ist halt der

00:01:47.120 --> 00:01:49.300
Agau-Teil. Ja, genau, und das ist auch so ein bisschen

00:01:49.300 --> 00:01:50.140
der Präzedenzfall.

00:01:51.220 --> 00:01:52.940
Früher war Apple ja immer so, ja,

00:01:53.120 --> 00:01:55.180
es ist auf deinem Gerät und es ist alles sicher und wir können

00:01:55.180 --> 00:01:57.180
da gar nicht. Und jetzt ist es so, ja, wir gucken doch mal rein.

00:01:58.280 --> 00:01:59.520
Ja, also

00:01:59.520 --> 00:02:00.740
entweder war es ein Unfall,

00:02:01.980 --> 00:02:03.340
sozusagen, dass jemand nicht drüber nachgedacht hat,

00:02:03.700 --> 00:02:05.240
dass, wenn man das so sagt, dass das dann genau

00:02:05.240 --> 00:02:06.780
das auslöst bei den Leuten.

00:02:07.520 --> 00:02:09.260
Oder es ist halt irgendwie, aber das kann ich

00:02:09.260 --> 00:02:11.140
mir auch nicht vorstellen, weil das wäre ja so

00:02:11.140 --> 00:02:13.140
ein abrupter Strategiewechsel. Das wäre auch schon

00:02:13.140 --> 00:02:15.320
irgendwie komisch. Also insofern nehme ich mal an,

00:02:15.380 --> 00:02:16.560
dass es eher ein PR-Unfall ist.

00:02:17.300 --> 00:02:19.220
Man weiß es nicht. Aber es ist ein

00:02:19.220 --> 00:02:21.220
Präzedenzfall. Apple scannt jetzt Inhalte

00:02:21.220 --> 00:02:22.180
auf euren Geräten.

00:02:22.180 --> 00:02:24.180
Das machen sie

00:02:25.180 --> 00:02:27.200
Das machen sie ja auch sowieso schon immer.

00:02:27.380 --> 00:02:29.220
Also man kann ja auch in der Fotos-App

00:02:29.220 --> 00:02:31.080
irgendwie nach Hund gucken

00:02:31.080 --> 00:02:32.340
oder nach Personen oder sonst irgendwas.

00:02:32.880 --> 00:02:35.340
Und da ist tatsächlich, das ist halt die gute Technik

00:02:35.340 --> 00:02:36.960
sozusagen, die da verwendet wird.

00:02:37.320 --> 00:02:39.580
Und ja, man kann sogar...

00:02:39.580 --> 00:02:41.440
Aber auch da sind viele Sachen falsch einsortiert.

00:02:41.800 --> 00:02:43.320
Ja, aber sie sind da auch

00:02:43.320 --> 00:02:44.880
halbwegs schnell und so. Man kann auch nach

00:02:44.880 --> 00:02:47.040
Vaccination oder so suchen und dann findet es den Impfpass,

00:02:47.120 --> 00:02:48.240
wenn man den fotografiert hat und so.

00:02:48.680 --> 00:02:51.220
Also da machen sie auch wirklich das gute

00:02:51.220 --> 00:02:51.480
Zeug.

00:02:52.860 --> 00:02:53.800
Und machen das halt

00:02:53.800 --> 00:02:54.620
auf dem Gerät selber.

00:02:55.180 --> 00:03:07.100
Aber genau, nur halt, wenn man selber sagt, man hätte das gern und ja, und halt, es wird auch nicht an irgendwen geschickt. Und jetzt ist das natürlich eine andere Sache, wenn sie jetzt irgendwas eines von den verbotenen Bildern findet, dann sagt es irgendwie dann Petzl.

00:03:07.100 --> 00:03:08.300
Vielleicht verbotene Bilder?

00:03:09.040 --> 00:03:10.200
Ja, wer weiß.

00:03:11.200 --> 00:03:19.320
Genau, und wir wissen auch, dass es da welche gibt, ja. Also das ist natürlich alles sehr unangenehm und das wäre dann schon ein Präsenzfall, weil das haben sie bisher nicht gemacht.

00:03:20.460 --> 00:03:25.020
Na gut, mal sehen, wie sich das entwickelt. PR-mäßig ist es auf jeden Fall ein mittleres Resultat.

00:03:25.020 --> 00:03:27.160
und das ist von einem Impfpass gesagt, das heißt, du bist auch jetzt durch.

00:03:27.920 --> 00:03:29.420
Ich bin schon lange durch.

00:03:29.720 --> 00:03:30.500
Ich auch jetzt seit einer Woche.

00:03:31.920 --> 00:03:35.360
Also hier auch nochmal der Aufruf von allen Zuhörern, lasst euch bitte impfen.

00:03:36.200 --> 00:03:37.360
Ja, das ist eine gute Idee.

00:03:37.420 --> 00:03:38.200
Wie viele haben wir jetzt verloren?

00:03:40.220 --> 00:03:41.200
Die Zuhörer.

00:03:41.320 --> 00:03:45.240
Es gab so einen tollen Rant-Post von Linus Torwalser.

00:03:45.280 --> 00:03:48.120
Ja, der sagt auch, lasst euch impfen, ihr Trottel.

00:03:49.340 --> 00:03:49.640
Ja, genau.

00:03:49.640 --> 00:03:50.900
auf der Tour.

00:03:52.540 --> 00:03:53.900
Ja, Linus Torwalds

00:03:53.900 --> 00:03:55.780
benutzt noch mehr ausgewählte Wörter,

00:03:55.880 --> 00:03:57.960
um das zu beschreiben, sagen wir es mal so.

00:03:59.420 --> 00:04:00.160
Ja, aber inhaltlich

00:04:00.160 --> 00:04:02.200
doch. Inhaltlich war es die Zusammenfassung, ja.

00:04:02.440 --> 00:04:03.440
Ja, haben wir noch Python-News?

00:04:03.880 --> 00:04:05.580
Ja, also eine

00:04:05.580 --> 00:04:07.600
News, die so ein bisschen anschließt an

00:04:07.600 --> 00:04:10.020
unsere letzte Episode zu Packaging,

00:04:10.700 --> 00:04:11.720
ist, dass tatsächlich,

00:04:11.860 --> 00:04:13.640
das war vielleicht schon länger klar,

00:04:13.720 --> 00:04:15.320
aber mir war es halt noch nicht klar, ab

00:04:15.320 --> 00:04:16.920
Python 3.11

00:04:16.920 --> 00:04:19.340
wird Distutils

00:04:19.340 --> 00:04:20.080
halt deprecated.

00:04:21.680 --> 00:04:23.400
Und das heißt,

00:04:23.460 --> 00:04:25.440
man muss sich da an der Stelle dann halt mal was überlegen,

00:04:25.520 --> 00:04:26.280
was man dann so tut.

00:04:27.020 --> 00:04:28.580
Aber es gibt doch so viele Alternativen.

00:04:29.900 --> 00:04:31.620
Ja. Diverse Alternativen.

00:04:32.060 --> 00:04:32.720
Also die

00:04:32.720 --> 00:04:34.800
Pakete, die jetzt halt so

00:04:34.800 --> 00:04:36.700
ein richtiges Problemchen bekommen,

00:04:37.220 --> 00:04:38.460
sind halt sowas wie

00:04:38.460 --> 00:04:41.240
NumPy und SciPy und so, weil

00:04:41.240 --> 00:04:43.240
die haben nämlich, die erben nämlich von

00:04:43.240 --> 00:04:45.240
Distutils und haben da Extensions für gebaut

00:04:45.240 --> 00:04:46.200
und damit bauen sie halt alles.

00:04:46.200 --> 00:04:47.120
Ja, okay.

00:04:47.120 --> 00:04:48.940
und ja,

00:04:49.300 --> 00:04:50.960
also die gucken sich gerade andere Sachen an

00:04:50.960 --> 00:04:52.620
und

00:04:52.620 --> 00:04:54.920
tatsächlich gibt es da, also sie haben sich zum Beispiel

00:04:54.920 --> 00:04:56.540
CMake angeguckt oder halt auch

00:04:56.540 --> 00:04:58.200
Mason heißt das irgendwie

00:04:58.200 --> 00:05:00.620
und tatsächlich

00:05:00.620 --> 00:05:02.980
also ich manchmal, also sogar relativ

00:05:02.980 --> 00:05:04.860
häufig, ich habe ja hier so ein M1

00:05:04.860 --> 00:05:07.020
Mac auch und da passiert

00:05:07.020 --> 00:05:09.020
es durchaus, also wenn die Python-Version hochgeht oder so,

00:05:09.080 --> 00:05:10.220
ist es eigentlich immer so, dass wenn ich dann

00:05:10.220 --> 00:05:12.580
Projekte habe, die

00:05:12.580 --> 00:05:14.440
abhängig haben zu NumPy,

00:05:14.600 --> 00:05:16.620
Pandas oder so, dass das Ganze zwar kopiert werden muss,

00:05:17.120 --> 00:05:23.340
weil meistens ist das Update von Python halt schneller bei mir, als die Wheels draußen sind.

00:05:23.940 --> 00:05:27.800
Und dann muss ich das halt kompilieren und dann denke ich mir so, oh nein, jetzt dauert das wieder ein paar Minuten.

00:05:28.560 --> 00:05:33.580
Und tatsächlich dauert das bei NumPy, glaube ich, sieben Minuten irgendwie mit dem klassischen jetzt des Tutels.

00:05:34.560 --> 00:05:42.900
Und tatsächlich aber auf Mason basierten, hat hier jemand schon den Namen vergessen, angefangen damit rumzuexperimentieren, dauert es halt irgendwie noch vier Sekunden oder so.

00:05:42.900 --> 00:05:44.960
Also es ist hauptsächlich irgendwie

00:05:44.960 --> 00:05:46.040
Bauzeit,

00:05:47.060 --> 00:05:48.140
die da

00:05:48.140 --> 00:05:50.620
benötigt wird.

00:05:51.400 --> 00:05:52.520
Also insofern, mal gucken.

00:05:52.640 --> 00:05:54.200
Könnte sein, dass es alles schneller wird demnächst.

00:05:55.480 --> 00:05:56.920
Das wäre auch ein sehr positiver

00:05:56.920 --> 00:05:58.580
Effekt von dieser Deprecation.

00:05:59.420 --> 00:06:00.980
Genau. Und ansonsten,

00:06:01.080 --> 00:06:02.760
ja, ich glaube 3.11

00:06:02.760 --> 00:06:03.360
ist in der Beta.

00:06:04.600 --> 00:06:05.740
3.10 ist in der Beta.

00:06:06.900 --> 00:06:08.820
Ich glaube, jetzt um den Dreh

00:06:08.820 --> 00:06:09.540
ein Rieskandidat.

00:06:09.540 --> 00:06:09.740
Genau.

00:06:11.080 --> 00:06:12.400
Die Zahlen gehen so schnell hoch.

00:06:12.900 --> 00:06:14.300
Ja, ja, ja. Freuen wir uns schon.

00:06:15.220 --> 00:06:17.100
Also ich habe mal den GitHub Copilot,

00:06:17.140 --> 00:06:19.160
den wir auch schon mal kurz erwähnt hatten, ausprobiert.

00:06:19.240 --> 00:06:20.960
Da habe ich jetzt auch eine Beta-Einladung bekommen.

00:06:21.500 --> 00:06:23.220
Muss sagen, das ist echt toll.

00:06:23.740 --> 00:06:24.820
Also ich habe noch nie so einen

00:06:24.820 --> 00:06:26.500
super Effekt von einer KI erlebt.

00:06:26.660 --> 00:06:28.900
Ich finde es echt nice. Ich gebe ein, also ich habe

00:06:28.900 --> 00:06:30.440
jetzt die VS Code Extension dafür benutzt.

00:06:30.780 --> 00:06:33.000
Sowas wie Define and Fibonacci oder sowas.

00:06:33.100 --> 00:06:35.060
Und dann warte ich

00:06:35.060 --> 00:06:36.960
auf das Autocompletion und dann schreibt er mir die komplette

00:06:36.960 --> 00:06:38.860
Funktion inklusive Docstrings und Type Annotations

00:06:38.860 --> 00:06:40.840
als Type-Int und ich drücke einmal

00:06:40.840 --> 00:06:42.880
Tabulator und es ist fertig. Und das geht

00:06:42.880 --> 00:06:44.700
halt auch für Sachen, die ich selber schreibe. Wenn ich jetzt

00:06:44.700 --> 00:06:46.680
eine Klasse schreibe, verschiedene Methoden nehme, beispielsweise

00:06:46.680 --> 00:06:48.740
irgendwie HTTP-Methode.

00:06:48.800 --> 00:06:50.760
Ich habe jetzt irgendwie ein Get geschrieben, ne, in einer Klasse.

00:06:51.100 --> 00:06:52.860
Define, Get, bla bla bla. Und danach

00:06:52.860 --> 00:06:54.800
fange ich an mit Define und dann steckt er mir

00:06:54.800 --> 00:06:56.080
als nächstes vor, Post zu definieren.

00:06:56.920 --> 00:06:58.820
Und zwar auch mit genau den richtigen Parametern und so.

00:06:58.880 --> 00:07:00.040
Das sind solche Sachen, das ist halt einfach,

00:07:00.540 --> 00:07:02.360
der lernt halt aus seinem eigenen Code raus und das ist

00:07:02.360 --> 00:07:04.700
wow. Also ich bin wirklich beeindruckt davon,

00:07:04.780 --> 00:07:06.260
was das so macht. Also das ist so ein bisschen,

00:07:06.800 --> 00:07:08.660
man braucht keine Snippets mehr, ja, wenn man irgendwie

00:07:08.660 --> 00:07:10.420
Snippets-Sammlung hat, sondern man nimmt halt einfach dann

00:07:10.420 --> 00:07:12.640
das individualisierte Snippet und das ist

00:07:12.640 --> 00:07:42.620
und Jochen unterhalten sich über die Programmiersprache Python

00:07:42.640 --> 00:07:43.440
Modelle trainiert werden?

00:07:44.920 --> 00:07:45.440
Nein.

00:07:46.540 --> 00:07:50.680
Das ist halt etwas, was sich allmählich einbürgert.

00:07:51.260 --> 00:07:52.400
Der Begriff dafür nennt sich

00:07:52.400 --> 00:07:53.640
Self-Supervised Learning.

00:07:54.660 --> 00:07:56.100
Und zwar deswegen, weil man halt

00:07:56.100 --> 00:07:58.200
zum Beispiel auf Text

00:07:58.200 --> 00:08:00.580
relativ gut Modelle trainieren kann,

00:08:00.680 --> 00:08:01.780
ohne irgendwelche gelabelten Daten

00:08:01.780 --> 00:08:04.400
haben zu müssen. Was man ja normalerweise ist, ist immer das Problem

00:08:04.400 --> 00:08:04.740
bei

00:08:04.740 --> 00:08:08.100
irgendwie, wenn man so überwachte

00:08:08.100 --> 00:08:09.060
Modelle, also

00:08:09.060 --> 00:08:12.400
anführungsweise normale Machine Learning Modelle

00:08:12.400 --> 00:08:14.680
trainiert, dann braucht man halt Trainingsdaten

00:08:14.680 --> 00:08:16.460
und damit meint man üblicherweise halt

00:08:16.460 --> 00:08:17.700
Daten, wo man

00:08:17.700 --> 00:08:20.600
Labels dran geschrieben hat, wie zum Beispiel

00:08:20.600 --> 00:08:22.860
jetzt, wenn man jetzt Bilder hat, so was ist ein Hund, das ist eine Katze

00:08:22.860 --> 00:08:24.500
und das ist, weiß ich nicht, irgendwas

00:08:24.500 --> 00:08:26.560
dazwischen oder so

00:08:26.560 --> 00:08:26.960
und

00:08:26.960 --> 00:08:30.480
bei Texten hat man das ja auch,

00:08:30.540 --> 00:08:32.720
da gibt es dann ein klassisches Problem wie Textkategorisierung,

00:08:32.880 --> 00:08:34.400
da hast du halt einen Text und dann steht halt zum Beispiel so

00:08:34.400 --> 00:08:36.020
diese Newsreuters-Artikel, da steht dran,

00:08:36.120 --> 00:08:38.600
das ist jetzt Sport oder das ist Politik oder das ist halt irgendwas anderes

00:08:38.600 --> 00:08:40.400
und

00:08:40.400 --> 00:08:43.940
und... Cool wäre ja so das Label wie, will ich lesen, will ich nicht lesen?

00:08:44.860 --> 00:08:45.860
Kann man auch alles machen.

00:08:46.040 --> 00:08:50.340
Wenn du da Trainingsdaten hast, dann kannst du Modelle drauf trainieren, die dann auch wahrscheinlich

00:08:50.340 --> 00:08:54.400
halbwegs gut funktionieren sollten, also das geht alles. Aber das Problem ist

00:08:54.400 --> 00:08:58.120
natürlich, dass für die meisten Probleme, die man so hat, hat man halt eben keine Trainingsdaten und das

00:08:58.120 --> 00:09:02.020
Erstellen von Trainingsdaten ist halt so aufwendig, dass sich das dann meistens nicht lohnt, das zu machen.

00:09:02.240 --> 00:09:06.660
Wie viel braucht man denn da, ungefähr 100.000? Also kommt drauf an, wie gut es sein soll.

00:09:06.660 --> 00:09:08.460
und dann entsprechend

00:09:08.460 --> 00:09:11.280
unter Umständen schon Millionen von Beispielen oder so

00:09:11.280 --> 00:09:13.120
und das ist dann halt doof, weil das ist einfach zu viel.

00:09:13.560 --> 00:09:15.080
Die meisten Leute haben so viele Beispiele gar nicht.

00:09:15.340 --> 00:09:17.420
Nee, genau. Also einmal, du hast

00:09:17.420 --> 00:09:19.000
gar nicht genug Beispiele, um sie labeln zu können,

00:09:19.080 --> 00:09:20.980
dann musst du die erstmal besorgen, dann musst du es auch noch irgendwie labeln

00:09:20.980 --> 00:09:23.120
und dann hast du Fehler in den Labels, weil

00:09:23.120 --> 00:09:25.100
halt die Leute das nicht perfekt gemacht haben und dann

00:09:25.100 --> 00:09:26.460
musst du das irgendwie kontrollieren und

00:09:26.460 --> 00:09:29.220
dann schwuppdiwupp hast du irgendwie so ein Redaktionssystem

00:09:29.220 --> 00:09:31.600
und eine Redaktion, eine technische Redaktion

00:09:31.600 --> 00:09:33.140
und dann Prozesse und

00:09:33.140 --> 00:09:35.020
keine Ahnung und Abstimmungen und das kostet

00:09:35.020 --> 00:09:37.080
Schweinegeld und das macht dann halt keiner so einfach so.

00:09:37.540 --> 00:09:39.180
Sondern nur, wenn man es halt wirklich, wirklich braucht.

00:09:40.380 --> 00:09:40.400
Und

00:09:40.400 --> 00:09:43.020
ja, aber

00:09:43.020 --> 00:09:45.180
man kann halt aus Text auch

00:09:45.180 --> 00:09:46.620
lernen, ohne diese ganzen Geschichten

00:09:46.620 --> 00:09:48.460
haben zu müssen. Also

00:09:48.460 --> 00:09:50.620
es gab ein Paper 2017,

00:09:50.980 --> 00:09:53.120
ist das glaube ich irgendwie, Attention is all you need.

00:09:53.200 --> 00:09:55.300
Da wurde halt diese Transformer-Architektur

00:09:55.300 --> 00:09:57.020
eingeführt und

00:09:57.020 --> 00:09:59.400
diese

00:09:59.400 --> 00:10:01.060
Dinge funktionieren auf Sprache halt total super.

00:10:01.600 --> 00:10:04.940
die funktionieren so,

00:10:05.020 --> 00:10:35.000
und Jochen unterhalten sich über die Programmiersprache Python

00:10:35.020 --> 00:10:37.380
in die Richtung, dass es das halt beim nächsten Mal besser macht.

00:10:37.920 --> 00:10:39.300
Und das machen wir dann ganz oft

00:10:39.300 --> 00:10:41.600
und dann kann es halt

00:10:41.600 --> 00:10:43.380
aus einem Text, ohne dass man da irgendwelche Labels

00:10:43.380 --> 00:10:45.260
explizit für bräuchte oder so,

00:10:45.760 --> 00:10:47.080
Dinge lernen, und zwar fast alles.

00:10:47.200 --> 00:10:48.120
Und das ist halt das Interessante.

00:10:49.040 --> 00:10:51.260
Man kann das gesamte Internet nehmen

00:10:51.260 --> 00:10:53.180
und dann lernt es halt

00:10:53.180 --> 00:10:54.700
lustigerweise eben nicht nur

00:10:54.700 --> 00:10:57.300
irgendwie so stumpf, welches Wort

00:10:57.300 --> 00:10:59.400
die höchste Wahrscheinlichkeit hat,

00:10:59.440 --> 00:11:01.500
dazustehen, sondern um das gut machen

00:11:01.500 --> 00:11:03.180
zu können, lernt es halt auch eine ganze Menge

00:11:03.180 --> 00:11:05.200
Konzepte und wie Dinge in Verhältnissen

00:11:05.200 --> 00:11:07.260
stehen und solche Sachen. Auch Kontext tatsächlich,

00:11:07.380 --> 00:11:08.480
das ist halt spannend. Also zum Beispiel

00:11:08.480 --> 00:11:10.780
das Plugin schafft das halt auch,

00:11:11.200 --> 00:11:13.260
Kommentare richtig zu schreiben. Das heißt, ich fange

00:11:13.260 --> 00:11:15.200
mit einem Kommentar an, zwei Worte, und das macht

00:11:15.200 --> 00:11:17.340
einen relativ guten Vorschlag für, was da stehen sollte.

00:11:18.900 --> 00:11:19.860
Ja, ja, ja, genau.

00:11:20.040 --> 00:11:22.100
Das ist eine

00:11:22.100 --> 00:11:23.480
Geschichte, die man halt auch machen kann, dass man sagt,

00:11:23.580 --> 00:11:25.640
okay, das ist ein Text, der Rest ist halt Lücke,

00:11:25.760 --> 00:11:27.880
dann füll mal. Und dann kommen da auch

00:11:27.880 --> 00:11:29.160
schon ganz interessante Geschichten bei raus.

00:11:29.860 --> 00:11:31.720
Also wenn man sich diese generierten Texte

00:11:31.720 --> 00:11:33.560
anguckt, dann ist halt schon immer so, dass man

00:11:33.560 --> 00:11:35.620
irgendwann wird so leicht absurd oder

00:11:35.620 --> 00:11:37.580
sehr verdreht irgendwie und

00:11:37.580 --> 00:11:39.760
merkt so, okay, so ganz, schon so ein bisschen

00:11:39.760 --> 00:11:41.940
neben der Spur. Ja, man kann es halt schnell kaputt machen.

00:11:42.040 --> 00:11:43.160
Ja, die nähern dann auch so ein bisschen.

00:11:43.920 --> 00:11:45.500
Wenn man halt so ein bisschen nicht falsch ist.

00:11:46.640 --> 00:11:47.680
Kann man es schnell kaputt machen,

00:11:47.740 --> 00:11:49.340
dann kann es immer so. Ja, ich habe noch

00:11:49.340 --> 00:11:51.560
was dazu gelesen,

00:11:51.760 --> 00:11:53.600
was in eine andere Richtung geht, dass es jetzt

00:11:53.600 --> 00:11:55.440
wohl eine große Anzahl inzwischen von

00:11:55.440 --> 00:11:56.940
wissenschaftlichen Veröffentlichungen gibt,

00:11:57.760 --> 00:11:59.560
denen man durch Analyse

00:11:59.560 --> 00:12:01.500
ansehen kann, dass eben nicht von

00:12:01.500 --> 00:12:04.040
im Menschen geschrieben würden, sondern von einem neuronalen Netzwerk.

00:12:04.940 --> 00:12:06.060
Und die Technik,

00:12:06.140 --> 00:12:07.660
die die da verwendet haben, die ist total witzig,

00:12:07.740 --> 00:12:09.800
weil diese Netzwerke für

00:12:09.800 --> 00:12:11.800
so Paper-Generierung

00:12:11.800 --> 00:12:13.280
und für Text-Generierung generell,

00:12:13.360 --> 00:12:15.740
die werden wohl bestraft, wenn sie Plagiate

00:12:15.740 --> 00:12:17.420
erzeugen. Weil das willst du natürlich nicht.

00:12:17.520 --> 00:12:19.720
Du willst natürlich nicht ein Paper einreichen, das dann als Plagiate

00:12:19.720 --> 00:12:21.180
abgerichtet wird. Und deshalb

00:12:21.180 --> 00:12:23.960
wählen die sehr viele Synonyme.

00:12:24.160 --> 00:12:25.360
Die sprechen sehr viel in Synonymen.

00:12:25.940 --> 00:12:27.800
Und auch eben so Fachbegriffe

00:12:28.620 --> 00:12:29.800
werden dann oft in Synonymen

00:12:29.800 --> 00:12:32.740
genommen. Das nette Beispiel,

00:12:32.820 --> 00:12:34.480
was ich erkenne, war eben, dass da die Paper

00:12:34.480 --> 00:12:36.000
über Big Data, die haben die ganze Zeit über

00:12:36.000 --> 00:12:37.300
Colossal Information gesprochen.

00:12:38.720 --> 00:12:40.300
Was eben kein normaler Mensch

00:12:40.300 --> 00:12:42.340
schreiben würde. Und dann haben sie eben gesucht, wie oft

00:12:42.340 --> 00:12:43.980
dieser Begriff

00:12:43.980 --> 00:12:46.180
Colossal Information in den Papern

00:12:46.180 --> 00:12:48.180
vorkommt und die dann eben genauer

00:12:48.180 --> 00:12:50.260
angesehen und die hatten eben

00:12:50.260 --> 00:12:52.140
alle diese Anzeichen von erzeugten Papern.

00:12:52.300 --> 00:12:54.180
Und das ist so ein bisschen jetzt quasi

00:12:54.180 --> 00:12:56.180
die Kehrseite von Copilot, dass die eben nicht

00:12:56.180 --> 00:12:58.220
nur, man muss es dann trotzdem noch für was

00:12:58.220 --> 00:13:00.160
Gutes einsetzen und nicht für

00:13:00.160 --> 00:13:02.080
Ja, du bist ja schon

00:13:02.080 --> 00:13:03.300
da, du brauchst Pages beizutreiben.

00:13:04.400 --> 00:13:05.460
Ja, aber

00:13:05.460 --> 00:13:07.400
genau, was ich

00:13:07.400 --> 00:13:09.860
noch erwähnen wollte, war,

00:13:10.220 --> 00:13:12.160
genau, man kann jetzt halt sozusagen Modelle trainieren

00:13:12.160 --> 00:13:14.100
auf allen Texten, die es im Internet gibt

00:13:14.100 --> 00:13:15.540
und die lernen halt tatsächlich da auch

00:13:15.540 --> 00:13:17.980
Dinge dann raus und das ist natürlich total super und das geht

00:13:17.980 --> 00:13:19.760
bei Sprache vor allen Dingen deswegen, weil

00:13:19.760 --> 00:13:22.260
man halt eine endliche

00:13:22.260 --> 00:13:24.220
Anzahl von möglichen

00:13:26.920 --> 00:13:27.320
Füllern

00:13:27.320 --> 00:13:29.320
sozusagen für die Lücken. Was? Noam Chomsky

00:13:29.320 --> 00:13:30.620
würde dir widersprechen, Jochen?

00:13:31.020 --> 00:13:33.440
Ja, ja gut. Aber man kann sich da ja beschränken.

00:13:33.580 --> 00:13:35.080
Man kann ja sagen, okay, meine Sprache hat nur

00:13:35.080 --> 00:13:37.000
20.000, 30.000

00:13:37.000 --> 00:13:39.320
Vokabeln

00:13:39.320 --> 00:13:41.320
und das war's. So größer ist mein Vocabulary

00:13:41.320 --> 00:13:43.360
einfach nicht. Ja, okay. Und wenn du immer nur ein Wort

00:13:43.360 --> 00:13:45.240
rausnimmst, ist natürlich klar. Und unter denen

00:13:45.240 --> 00:13:47.480
wird auch eins sein, das hinreichend nah dran ist.

00:13:47.540 --> 00:13:49.340
Und dann kannst du eben allen Worten

00:13:49.340 --> 00:13:51.260
eine Wahrscheinlichkeit zuweisen. Du kannst halt sagen,

00:13:51.380 --> 00:13:53.580
okay, das ist jetzt sehr, sehr unwahrscheinlich

00:13:53.580 --> 00:13:55.360
und das ist jetzt irgendwie, dass das geht.

00:13:55.680 --> 00:13:56.480
Das sind alle sehr unwahrscheinlich.

00:13:56.480 --> 00:13:59.420
Es gibt dann bestimmt das Wort wie F, das was überall hinpasst.

00:14:00.180 --> 00:14:00.560
Ja klar.

00:14:03.780 --> 00:14:04.680
Aber das Modell,

00:14:05.040 --> 00:14:06.540
das dann halt auch, das Modell, das

00:14:06.540 --> 00:14:08.800
damit trainiert wird, passt dann aber nicht mehr überall hin, wenn du das

00:14:08.800 --> 00:14:10.720
als akzeptiert hast.

00:14:12.600 --> 00:14:13.100
Kennen wir leider.

00:14:16.380 --> 00:14:17.140
Jedenfalls, genau.

00:14:17.600 --> 00:14:18.880
Also mit Sprache geht das

00:14:18.880 --> 00:14:21.020
total super und eben

00:14:21.020 --> 00:14:22.680
Copilot ist halt dann

00:14:22.680 --> 00:14:24.900
quasi auch eine Folge. Das Tolle ist, dass man

00:14:24.900 --> 00:14:26.820
jetzt. Modelle, die da drauf trainiert sind,

00:14:26.900 --> 00:14:28.980
kann man jetzt mit ganz wenig Trainingsbeispielen

00:14:29.560 --> 00:14:29.880
auf das

00:14:29.880 --> 00:14:33.260
Problem, das man wirklich hat,

00:14:33.440 --> 00:14:34.880
adaptieren. Also da braucht man dann nur noch

00:14:34.880 --> 00:14:36.700
ein paar Trainingsbeispiele, also

00:14:36.700 --> 00:14:38.380
nicht mehr viele. Ja, ich glaube auch,

00:14:38.600 --> 00:14:40.760
er macht das tatsächlich anhand des Repos,

00:14:40.840 --> 00:14:42.640
was du gerade auffasst. Kann er schon gucken

00:14:42.640 --> 00:14:44.760
und kann da schon dann die Completion zum Beispiel oder die

00:14:44.760 --> 00:14:46.860
Vorschläge anpassen auf das, was du da gerade machen

00:14:46.860 --> 00:14:48.220
willst. Und das ist schon echt wow.

00:14:48.580 --> 00:14:50.520
Ja, und das ist halt natürlich total toll, weil

00:14:50.520 --> 00:14:52.640
das dann halt läuft,

00:14:52.640 --> 00:14:54.640
dass du im Grunde dieses Trainingsproblem

00:14:54.900 --> 00:14:57.000
Trainingsdatenproblem loswirst.

00:14:58.160 --> 00:14:59.060
Und ja,

00:14:59.600 --> 00:15:00.920
eine ganze Menge Anwendungsfälle

00:15:00.920 --> 00:15:03.000
plötzlich von, ist zu aufwendig,

00:15:03.080 --> 00:15:05.020
unlösbar, lohnt sich nicht, in Richtung

00:15:05.020 --> 00:15:06.460
kann man schon mal probieren,

00:15:06.640 --> 00:15:09.040
wandern und dann ist es natürlich toll.

00:15:09.240 --> 00:15:10.860
Und ja, also da wird es

00:15:10.860 --> 00:15:12.500
eine Menge interessante Anwendungen geben.

00:15:12.720 --> 00:15:14.920
Also gerade für die ganzen V-Programmierer unter uns, also das ganze

00:15:14.920 --> 00:15:16.840
Zeug drumherum, das geht halt einfach jetzt viel

00:15:16.840 --> 00:15:17.500
automatisierter.

00:15:17.980 --> 00:15:21.000
Ja, Kinderregegen, das ist schlecht für die

00:15:21.000 --> 00:15:22.980
Auftragsprogrammierer.

00:15:22.980 --> 00:15:24.600
Das finde ich nicht gut.

00:15:24.900 --> 00:15:25.760
Das kann schon sein.

00:15:26.380 --> 00:15:26.560
Ja.

00:15:29.080 --> 00:15:30.960
Aber genau, das Problem

00:15:30.960 --> 00:15:32.720
ist aber jetzt, dass man das nicht

00:15:32.720 --> 00:15:34.600
machen kann für, also was halt, also

00:15:34.600 --> 00:15:36.300
man würde, wäre sehr viel weiter,

00:15:36.640 --> 00:15:38.260
wenn man das jetzt auch für zum Beispiel

00:15:38.260 --> 00:15:40.580
Bilddaten machen könnte. Also und

00:15:40.580 --> 00:15:42.500
tatsächlich ist es wohl so, dass es da

00:15:42.500 --> 00:15:46.780
gibt es auch inzwischen Forschung zu,

00:15:46.820 --> 00:15:48.700
das ist halt tatsächlich der Weg, also man hat sich ja das

00:15:48.700 --> 00:15:50.640
oft lange, oder ich erinnere mich noch dran,

00:15:50.680 --> 00:15:51.900
dass es mal völlig unklar war, wie das

00:15:51.900 --> 00:15:54.720
eigentlich funktioniert, wie lernen Kinder eigentlich

00:15:54.720 --> 00:16:02.040
sozusagen so schnell Dinge, man versteht es nicht, sie sehen eigentlich zu wenig Trainingsbeispiele

00:16:02.040 --> 00:16:09.040
für das, was sie da lernen und tatsächlich lernen sie ja auch so etwas, was einem die

00:16:09.040 --> 00:16:13.320
Forschung sagt, manchmal Schwierigkeiten hat, das einfach so zu akzeptieren, aber die sagt

00:16:13.320 --> 00:16:17.520
halt, das meiste, was Menschen so lernen, lernen sie halt so in den ersten neun Monaten

00:16:17.520 --> 00:16:21.800
und alles, was danach kommt, ist halt so, naja Gott, also ich meine so Details, also

00:16:21.800 --> 00:16:24.060
Die wesentlichen Dinge sind bis dahin gelernt.

00:16:24.360 --> 00:16:25.480
Wie machen die das denn?

00:16:26.040 --> 00:16:27.840
Kinder in dem Alter verstehen einfach gar nichts.

00:16:28.600 --> 00:16:30.140
Die kennen auch keine Worte für nichts.

00:16:30.280 --> 00:16:31.600
Wieso können die denn so viel lernen?

00:16:31.960 --> 00:16:33.620
Wie soll das gehen? Das ist irgendwie alles seltsam.

00:16:34.520 --> 00:16:36.160
Und tatsächlich ist es wohl so,

00:16:36.240 --> 00:16:37.320
dass die halt auch schon eine Art

00:16:37.320 --> 00:16:39.840
Self-Supervised Learning machen

00:16:39.840 --> 00:16:42.260
und quasi genau das gleiche Prinzip irgendwie

00:16:42.260 --> 00:16:44.480
sehen halt was

00:16:44.480 --> 00:16:46.380
und Dinge passieren

00:16:46.380 --> 00:16:48.220
und dann betrachten sie das

00:16:48.220 --> 00:16:50.240
sozusagen als eine Art Lückentext und füllen das dann halt

00:16:50.240 --> 00:16:50.740
und das funktioniert.

00:16:50.740 --> 00:16:52.740
Genau, das ist das Ego, was das dann macht

00:16:52.740 --> 00:16:54.400
Na, keine Ahnung

00:16:54.400 --> 00:16:56.440
Ja, aber das zieht das dann irgendwo aus dem Äther, irgendwelche

00:16:56.440 --> 00:16:58.700
Formationen schafft das dann natürlich und deswegen hast du ja auch

00:16:58.700 --> 00:17:00.820
so, weiß nicht, ob ihr das kennt, wenn ihr irgendwo

00:17:00.820 --> 00:17:02.660
müde seid oder sowas, dann werden bestimmte Sachen

00:17:02.660 --> 00:17:04.840
ja auch einfach ersetzt, der Kopf macht das ja sehr gerne

00:17:04.840 --> 00:17:06.600
dass er bestimmte Flecken, die

00:17:06.600 --> 00:17:08.620
nicht so ganz klar sind, dann mit Sachen überschreift

00:17:08.620 --> 00:17:10.580
also einige Leute, die haben dann auch

00:17:10.580 --> 00:17:12.600
innere Stimme, die dann auf einmal das erste Mal vollständig

00:17:12.600 --> 00:17:13.960
die nur so halb gehört haben oder

00:17:13.960 --> 00:17:16.840
das kannst du auch mit optischen Informationen machen oder mit

00:17:16.840 --> 00:17:18.920
anderen optischen Signalen

00:17:18.920 --> 00:17:20.400
und das ist halt super spannend tatsächlich

00:17:20.400 --> 00:17:22.040
und wenn das halt self-supervised learning ist,

00:17:22.420 --> 00:17:24.240
dann ist ja auch klar, dann hast du so ein Lückenbild.

00:17:24.540 --> 00:17:26.220
Das ist so ein bisschen so, du hast ein Foto,

00:17:26.380 --> 00:17:28.300
da fehlt ein Teil und dann wird das automatisch ersetzt.

00:17:28.700 --> 00:17:30.000
Das ist spannend, wenn die KI das kann, dann kann man

00:17:30.000 --> 00:17:31.920
quasi, machst du ein Hochzeitsbild von dir, dann kannst du irgendwie

00:17:31.920 --> 00:17:34.400
deinen Partner rausschneiden, dann kannst du den idealen Partner auf einmal sehen.

00:17:35.920 --> 00:17:36.480
Ah ja, und

00:17:36.480 --> 00:17:38.240
so ist also dieses Python

00:17:38.240 --> 00:17:39.820
Import-System entstanden.

00:17:40.540 --> 00:17:41.180
Das ist ja spannend.

00:17:41.700 --> 00:17:42.880
Wie, willst du jetzt zum Topic zurück?

00:17:44.000 --> 00:17:46.040
Nein, nein. Nur ganz kurz, also

00:17:46.040 --> 00:17:48.080
das, was halt momentan nicht geht, was man nicht

00:17:48.080 --> 00:17:50.240
hinkriegt und was halt total toll wäre, wenn man es irgendwie hinkriegen würde,

00:17:50.240 --> 00:17:51.600
also vielleicht hat ja irgendjemand eine Idee

00:17:51.600 --> 00:17:54.560
das große ungelöste Problem an der Stelle ist halt

00:17:54.560 --> 00:17:56.240
wenn du jetzt ein Bild aus einem

00:17:56.240 --> 00:17:58.180
Teil aus einem Bild rausnimmst und sagst so

00:17:58.180 --> 00:18:00.320
das ist jetzt leer, also einmal

00:18:00.320 --> 00:18:02.340
man kann halt irgendwie die

00:18:02.340 --> 00:18:04.400
Menge an Bildern, die halt an der Stelle möglich wären

00:18:04.400 --> 00:18:05.580
nicht aufzählen, nicht so richtig

00:18:05.580 --> 00:18:07.320
und dann ist es so

00:18:07.320 --> 00:18:10.380
selbst wenn man sich irgendwie beschränkt

00:18:10.380 --> 00:18:12.480
weiß man nicht, so jetzt hat man

00:18:12.480 --> 00:18:14.360
zwei Sachen, die eigentlich offensichtlich nichts damit zu tun haben

00:18:14.360 --> 00:18:16.440
mit dem Bild, das man eigentlich an der

00:18:16.440 --> 00:18:18.340
Stelle gerne hätte, welche Wahrscheinlichkeit weiß man

00:18:18.340 --> 00:18:20.180
hinzu und wie ist der Gradient in welche Richtung.

00:18:20.240 --> 00:18:22.420
Aber vielleicht braucht man da den Kontext für, weil wenn du einen Kontext

00:18:22.420 --> 00:18:24.220
hast, in dem das drumherum gestellt werden soll,

00:18:24.720 --> 00:18:26.260
der halt selber ein Objekt ist,

00:18:26.300 --> 00:18:28.160
das viele verschiedene Informationen beinhaltet, dann ist es

00:18:28.160 --> 00:18:30.360
besser, diese Menge an

00:18:30.360 --> 00:18:32.160
abzählbaren Elementen zu bilden und das entsprechend

00:18:32.160 --> 00:18:34.240
herauszusuchen mit der höchsten Wahrscheinlichkeit.

00:18:34.320 --> 00:18:36.100
Das heißt also, ohne Kontext ist das wahrscheinlich nicht so

00:18:36.100 --> 00:18:38.340
einfach möglich, dass du einfach so ein Bild machst, das dann gut trifft.

00:18:38.520 --> 00:18:40.320
Aber wenn du Informationen über den Kontext hast,

00:18:40.340 --> 00:18:41.920
in dem du dieses Bild ersetzen möchtest...

00:18:41.920 --> 00:18:44.240
Also der Punkt ist eher, das ist ja möglich.

00:18:44.240 --> 00:18:46.300
Also du kannst ja durchaus ein Modell trainieren,

00:18:46.400 --> 00:18:47.800
was dann irgendwas vorhersagt an der Stelle.

00:18:47.800 --> 00:18:52.840
Die Frage ist nur, welchen Wert hat das, was es jetzt vorhergesagt hat?

00:18:53.000 --> 00:18:57.060
Hat das jetzt die Wahrscheinlichkeit 0,376 oder 0,652?

00:18:57.540 --> 00:19:03.960
Und das macht ja einen Unterschied fürs Training, aber es ist halt völlig unklar, wie man da die Wahrscheinlichkeit ausrechnen soll.

00:19:04.740 --> 00:19:08.000
Ja, vielleicht braucht man dafür echt einen Kontext, in der es eingesetzt werden soll.

00:19:08.120 --> 00:19:08.820
Das ist, glaube ich, gar nicht so.

00:19:09.480 --> 00:19:11.580
Ja, also das ist auf jeden Fall, wenn da jemand eine Idee hat, voll gut.

00:19:12.360 --> 00:19:16.340
Aber das war jetzt auch gerade wieder so ein Ding, was halt passiert, wenn man halt den Kontext nicht hat.

00:19:16.340 --> 00:19:18.460
dann passiert sowas wie ein Relative Import

00:19:18.460 --> 00:19:19.860
Beyond Top Level Package oder so.

00:19:20.140 --> 00:19:22.580
Oh, das ist ein Syntaxfehler quasi.

00:19:22.700 --> 00:19:24.060
Ich sehe schon, es gibt eine gewisse

00:19:24.060 --> 00:19:26.600
Abschüssigkeit in eine

00:19:26.600 --> 00:19:28.260
bestimmte Richtung. Ja, Importsystem ist auch

00:19:28.260 --> 00:19:29.820
voll interessant. Na gut.

00:19:31.160 --> 00:19:32.380
Ja, natürlich, das war gerade ein

00:19:32.380 --> 00:19:34.360
Versuch, da so ein bisschen hinzukommen, weil wir wollten ja über das

00:19:34.360 --> 00:19:36.400
Importsystem tatsächlich reden und

00:19:36.400 --> 00:19:37.480
wie man das in Python macht.

00:19:38.160 --> 00:19:40.400
Und ich glaube, als Basis irgendwie das so ein bisschen zu verstehen,

00:19:40.460 --> 00:19:42.320
es gibt einen super tollen Blog, den ich auch erst letztens

00:19:42.320 --> 00:19:44.240
entdeckt habe, der 10.000 Meters heißt,

00:19:44.240 --> 00:19:48.300
der irgendwie auf Hacker News nochmal gefeatured worden ist und da hat ein

00:19:48.300 --> 00:19:51.340
Mensch namens Viktor Skvorstov, wenn ich ihn richtig ausspreche,

00:19:52.200 --> 00:19:55.240
einen Artikel geschrieben, wie das Python-Import-System funktioniert.

00:19:56.520 --> 00:19:58.780
Und das hat er so ein bisschen erklärt, das ist sehr spannend zu lesen.

00:19:59.720 --> 00:20:02.980
Fangen wir auf jeden Fall in die Shownotes. Und ja, wie funktioniert denn das eigentlich?

00:20:03.540 --> 00:20:13.688
Was ist denn das Python Ja ich habe diesen Artikel auf Hacker News gesehen und auch die Diskussion dann so ein bisschen angeguckt und da ist mir aufgefallen dass das doch tats erstaunlich

00:20:13.688 --> 00:20:14.948
viel komplizierter ist, als

00:20:14.948 --> 00:20:17.668
man das so denkt oder als man das im Kopf hat.

00:20:19.748 --> 00:20:21.848
Was mir gar nicht so aufgefallen

00:20:21.848 --> 00:20:23.748
war, weil ich offenbar

00:20:23.748 --> 00:20:25.948
nicht alle Features benutze, die es da so gibt.

00:20:26.348 --> 00:20:28.007
Vielleicht ganz kurz, bevor wir darauf einsteigen,

00:20:28.007 --> 00:20:29.288
was ist denn überhaupt das Problem damit?

00:20:29.348 --> 00:20:31.768
Wir haben so eine Story gehört, dass das mal lange

00:20:31.768 --> 00:20:32.268
macht, was macht denn das?

00:20:33.328 --> 00:20:34.408
Worum geht es denn da überhaupt?

00:20:34.968 --> 00:20:37.048
Und warum braucht Python ein Import-System überhaupt?

00:20:37.148 --> 00:20:39.408
Das ist ja auch eine spannende Sache, weil in anderen Sprachen ist das ja anders

00:20:39.408 --> 00:20:41.668
gelöst und zum Teil besser und zum Teil

00:20:41.668 --> 00:20:42.028
schlechter.

00:20:44.668 --> 00:20:45.668
Wer will

00:20:45.668 --> 00:20:45.948
anfangen?

00:20:46.688 --> 00:20:49.588
Ich würde sagen, vielleicht kann man genauso anfangen wie der Artikel.

00:20:49.668 --> 00:20:51.068
Was passiert denn, wenn man sagt Import M?

00:20:52.388 --> 00:20:53.548
Warum sagt man das denn überhaupt,

00:20:53.668 --> 00:20:53.768
Jochen?

00:20:56.288 --> 00:20:57.848
Es gibt

00:20:57.848 --> 00:20:59.688
natürlich Build-Ins, aber nicht alles sind

00:20:59.688 --> 00:21:01.208
Build-ins und manchmal möchte man halt

00:21:01.208 --> 00:21:03.708
irgendwo Funktionen oder Klassen oder sonst

00:21:03.708 --> 00:21:04.448
irgendwas verwenden.

00:21:06.328 --> 00:21:07.568
Oder man möchte einfach seinen Code trennen

00:21:07.568 --> 00:21:08.888
und nicht alles in eine einzige Pfeile.

00:21:08.908 --> 00:21:11.728
Man möchte halt irgendwas verwenden, was nicht in der aktuellen Datei definiert ist.

00:21:13.188 --> 00:21:13.588
Genau.

00:21:13.748 --> 00:21:15.348
Und jetzt könnte ich verschiedene Dinge,

00:21:15.408 --> 00:21:17.488
ich könnte mir die Datei nehmen und sie

00:21:17.488 --> 00:21:19.608
e-ballen, könnte ich machen.

00:21:20.428 --> 00:21:20.568
Ja.

00:21:21.928 --> 00:21:22.288
Wäre

00:21:22.288 --> 00:21:24.688
auch möglich, oder?

00:21:24.688 --> 00:21:26.208
Wäre auch möglich.

00:21:26.208 --> 00:21:27.588
Hat auch einen ähnlichen Effekt irgendwie.

00:21:27.588 --> 00:21:29.708
tatsächlich. Aber das

00:21:29.708 --> 00:21:31.548
überschreibt dann natürlich manchmal Sachen, wenn ich jetzt irgendwie

00:21:31.548 --> 00:21:33.228
zum Beispiel da drin halt,

00:21:33.627 --> 00:21:35.868
wenn ich jetzt im aktuellen... Ja, vor allem, wenn man das rekursiv

00:21:35.868 --> 00:21:37.848
macht, weil das müsste dann auch immer weiter funktionieren.

00:21:37.968 --> 00:21:38.908
Ja. Und dann

00:21:38.908 --> 00:21:41.627
wenn man so Counter-Variablen hat oder so,

00:21:41.708 --> 00:21:42.868
die sind dann wahrscheinlich hinterher anders.

00:21:43.968 --> 00:21:45.768
Vielleicht, ja. Vielleicht. Ja, oder auch

00:21:45.768 --> 00:21:47.928
Namen, die einfach gängig sind,

00:21:48.188 --> 00:21:49.788
werden vielleicht eventuell überschrieben.

00:21:50.068 --> 00:21:51.668
Ja, aber das ist ja, bei Python macht der auch

00:21:51.668 --> 00:21:53.248
irgendwie sowas, ne? Das macht ja so ein

00:21:53.248 --> 00:21:55.768
Namespace wieder. Ja, genau. Aber das müsstest du dir

00:21:55.768 --> 00:21:57.568
dann, also wenn du einfach die Datei lädst

00:21:57.568 --> 00:21:59.448
und ausführst, also

00:21:59.448 --> 00:22:01.088
e-Val drauf machst, dann

00:22:01.088 --> 00:22:03.748
ja, kriegst du halt erstmal alles in die Hand.

00:22:04.388 --> 00:22:05.668
Und da wäre dann, hätte man

00:22:05.668 --> 00:22:07.608
dann auch wieder das Problem mit dieser Dekursion, die müssen wir auch irgendwie

00:22:07.608 --> 00:22:09.528
lösen, weil du musst ja dann eventuell noch mehr Sachen

00:22:09.528 --> 00:22:11.328
derweil

00:22:11.328 --> 00:22:13.308
importieren und e-Valen und

00:22:13.308 --> 00:22:15.528
vielleicht hast du ja sogar das Problem, dass

00:22:15.528 --> 00:22:17.088
du es zyklisch machst.

00:22:17.248 --> 00:22:18.608
Aber das Problem haben wir in Python auch.

00:22:19.068 --> 00:22:20.928
Das Problem haben wir in Python auch, ja, aber

00:22:20.928 --> 00:22:23.367
müssen wir mal überlegen, wie das das macht.

00:22:23.748 --> 00:22:25.408
Aber in anderen

00:22:25.408 --> 00:22:27.548
Sprachen, um da noch kurz drauf anzugehen,

00:22:27.608 --> 00:22:29.508
braucht man es ja, macht man es ja

00:22:29.508 --> 00:22:31.627
nicht. In Java oder in C++

00:22:31.627 --> 00:22:33.588
macht man es ja nicht, dass man einfach

00:22:33.588 --> 00:22:35.148
andere Dateien da reinkopiert,

00:22:36.168 --> 00:22:37.448
weil da ja

00:22:37.448 --> 00:22:39.448
die Organisation anders ist. Da braucht man ja quasi

00:22:39.448 --> 00:22:41.367
keine Objekte in der Hand, sondern nur

00:22:41.367 --> 00:22:43.528
einen Verweis auf die entsprechenden Stellen

00:22:43.528 --> 00:22:45.548
im Code. Das heißt, bei denen

00:22:45.548 --> 00:22:47.608
funktioniert das Import-System halt,

00:22:47.848 --> 00:22:49.548
weil das während des Kompilierens passiert,

00:22:50.468 --> 00:22:51.608
deutlich anders

00:22:51.608 --> 00:22:52.648
als in Python.

00:22:53.488 --> 00:22:55.608
Ja, ich überlege gerade, wo da die Unterschiede sind.

00:22:55.808 --> 00:22:58.528
Also wenn ich in C sage include,

00:22:59.168 --> 00:23:01.488
das wäre das eine Datei.

00:23:01.968 --> 00:23:03.528
Genau, aber wenn du zum Beispiel in C

00:23:03.528 --> 00:23:06.568
includeierst, die sind ja normalerweise nur .h-Dateien.

00:23:06.788 --> 00:23:10.488
Und da sind ja keine Definitionen drin,

00:23:10.588 --> 00:23:11.888
da sind ja nur Deklarationen drin.

00:23:12.168 --> 00:23:15.748
Da steht nur drin, es gibt etwas, was heißt so und so.

00:23:16.108 --> 00:23:18.288
Und das ist das Einzige, was du an der Stelle da reinkriegst.

00:23:18.948 --> 00:23:21.348
Das Zusammenführen, was dann tatsächlich der Code ist

00:23:21.348 --> 00:23:23.268
oder was diese Werte sind. Das passiert erst später

00:23:23.268 --> 00:23:25.328
im Link-Vorgang, wenn

00:23:25.328 --> 00:23:27.367
du schon alles kompiliert hast. Und diese

00:23:27.367 --> 00:23:29.367
Phasen gibt es bei Python ja einfach überhaupt

00:23:29.367 --> 00:23:31.228
nicht. Bei Python gibt es ja nur die Phase

00:23:31.228 --> 00:23:33.288
Ausführen. Und zu dem Zeitpunkt

00:23:33.288 --> 00:23:34.948
brauchst du es dann jetzt. Und

00:23:34.948 --> 00:23:36.708
was viele Leute vergessen,

00:23:37.367 --> 00:23:39.508
wenn du define schreibst, wenn du eine Funktion definierst,

00:23:40.508 --> 00:23:41.348
wenn du eine

00:23:41.348 --> 00:23:43.288
Funktion erstellst, dann ist

00:23:43.288 --> 00:23:45.388
das Code, der ausgeführt wird, das ist ein Befehl

00:23:45.388 --> 00:23:47.228
an Python und der heißt,

00:23:47.328 --> 00:23:49.328
merkt ihr mal unter dem Namen, keine Ahnung,

00:23:49.428 --> 00:23:51.188
fun, ein Code,

00:23:51.188 --> 00:23:53.168
Objekt, was folgende Eigenschaften hat.

00:23:53.228 --> 00:23:55.148
Es ist callable und dieser callable hat

00:23:55.148 --> 00:23:57.108
folgende Parameter und dann steht da

00:23:57.108 --> 00:23:59.048
Code drin und so weiter und so fort. Und auch

00:23:59.048 --> 00:24:00.408
bei Class, wenn du Class

00:24:00.408 --> 00:24:02.888
als Schlüsselwort, wird ja erstmal

00:24:02.888 --> 00:24:05.028
alles ausgeführt, was da drin ist. Das heißt, du kannst da

00:24:05.028 --> 00:24:06.388
prinzipiell Code drin haben, der

00:24:06.388 --> 00:24:09.148
Sachen tut, was ja auch an vielen Stellen

00:24:09.148 --> 00:24:11.168
sehr wichtig ist, was du aber in anderen

00:24:11.168 --> 00:24:12.488
Systemen nicht hast.

00:24:13.228 --> 00:24:14.688
In der Java und in der C++

00:24:14.688 --> 00:24:16.848
hast du das nicht, das wird nicht ausgeführt.

00:24:17.627 --> 00:24:19.028
Es wird zum Teil ausgeführt

00:24:19.028 --> 00:24:20.908
bei C, weil du da diesen komischen Preprocessor

00:24:20.908 --> 00:24:22.968
hast und weil der auch so

00:24:22.968 --> 00:24:25.028
constant optimizations

00:24:25.028 --> 00:24:26.208
versucht schon mal zu machen,

00:24:26.788 --> 00:24:28.728
aber generell wird

00:24:28.728 --> 00:24:30.888
C-Code erst ausgeführt, wenn du das Programm startest.

00:24:31.048 --> 00:24:31.728
Das ist bei Python,

00:24:33.068 --> 00:24:34.988
ja, also diesen Schritt des Kompilierens gibt es ja bei Python

00:24:34.988 --> 00:24:36.968
nicht, der ist ja da so ein bisschen innen drin.

00:24:37.568 --> 00:24:38.867
Das heißt, du kannst auch mit Import

00:24:38.867 --> 00:24:39.948
kannst du auch Sachen ausführen.

00:24:42.627 --> 00:24:43.008
Was

00:24:43.008 --> 00:24:44.568
manchmal komisch ist und manchmal gewünscht

00:24:44.568 --> 00:24:46.388
und manchmal überraschend.

00:24:47.308 --> 00:24:48.708
Ja, also das ist manchmal,

00:24:48.988 --> 00:24:50.867
also tatsächlich, wenn Sachen importiert

00:24:50.867 --> 00:24:52.708
und das dann halt alles in dem Modul ausgeführt wird,

00:24:52.808 --> 00:24:54.627
was auf dem Top-Level ist, das ist halt schon

00:24:54.627 --> 00:24:57.088
manchmal eher überraschend.

00:24:58.468 --> 00:24:59.428
Warum passiert das denn auch?

00:24:59.488 --> 00:25:00.908
Warum wird das dann ausgeführt? Also wenn man jetzt

00:25:00.908 --> 00:25:02.068
einen Import hat, Import M

00:25:02.068 --> 00:25:04.428
von irgendwo, was dann...

00:25:04.428 --> 00:25:06.867
Einfach nur Import M, also wirklich nur

00:25:06.867 --> 00:25:08.488
diese Zeile Import M. Was passiert dann?

00:25:09.268 --> 00:25:10.888
Ja, das ist eine gute Frage.

00:25:11.408 --> 00:25:12.848
Und auf den ersten Blick ist es

00:25:12.848 --> 00:25:14.668
finde ich so ein bisschen offensichtlich, was da passiert

00:25:14.668 --> 00:25:16.848
und auf den zweiten Blick ist es dann tatsächlich doch nicht so offensichtlich,

00:25:16.968 --> 00:25:18.588
wie eben dieser Artikel,

00:25:18.588 --> 00:25:20.888
glaube ich, uns allen demonstriert hat.

00:25:21.768 --> 00:25:23.068
Also für mich bedeutet Import M

00:25:23.068 --> 00:25:25.188
suche eine Datei,

00:25:25.308 --> 00:25:26.448
die M.py heißt

00:25:26.448 --> 00:25:29.148
und gib mir den Inhalt

00:25:29.148 --> 00:25:30.808
davon als Modul. Oh, das wäre aber ein Skript.

00:25:30.928 --> 00:25:32.588
Und wir könnten auch ein Modul laden.

00:25:32.688 --> 00:25:34.148
Wenn ein Modul heißt, das M heißt,

00:25:34.548 --> 00:25:35.968
das ist ein Verzeichnis oder sowas.

00:25:36.248 --> 00:25:39.068
Aber ein Verzeichnis ist ja

00:25:39.068 --> 00:25:40.728
auch nur so eine Art Datei.

00:25:41.248 --> 00:25:42.828
Ein Verzeichnis ist ja auch nur ein

00:25:42.828 --> 00:25:44.768
Verweis auf die Init.py.

00:25:44.768 --> 00:25:46.708
Es gibt Module und Packages

00:25:46.708 --> 00:25:47.867
und was ist denn überhaupt der Unterschied?

00:25:47.867 --> 00:25:49.668
was ein Skript, was ein Modul, was ein Package.

00:25:50.968 --> 00:25:52.388
Ja, das ist schwer zu sagen.

00:25:52.648 --> 00:25:53.788
Ich finde es schwer zu sagen, weil

00:25:53.788 --> 00:25:56.127
für mich dieser Unterschied wirklich minimal

00:25:56.127 --> 00:25:58.028
ist. Das eine ist halt

00:25:58.028 --> 00:26:00.328
eine Datei und das andere ist ein Verzeichnis, aber das Verzeichnis

00:26:00.328 --> 00:26:02.048
selber hat ja keinen Inhalt

00:26:02.048 --> 00:26:04.048
und deshalb tut man so, als ob die InitPy,

00:26:04.168 --> 00:26:05.908
die da drin ist, dass der Inhalt dieses

00:26:05.908 --> 00:26:06.728
Verzeichnisses ist.

00:26:08.788 --> 00:26:10.008
Genau, in der InitPy kann man auch

00:26:10.008 --> 00:26:11.908
sowas wie all dann definieren, das heißt, wenn man zum Beispiel sowas wie

00:26:11.908 --> 00:26:14.008
import as quick, dann kannst du auch eine einzelne

00:26:14.008 --> 00:26:15.928
Datei machen. Kannst du überall definieren.

00:26:15.928 --> 00:26:16.288
Ja, okay.

00:26:16.288 --> 00:26:20.568
Kannst du auch Slots definieren, das ist auch, kannst du auch überall machen.

00:26:20.808 --> 00:26:25.608
Ein Slot? Ja, das sind solche Sachen, die beim Import mitgebracht werden sollen.

00:26:29.308 --> 00:26:34.208
Genauso wie All, wenn du All definierst und dann machst du From M Import Stern, dann kriegst du alles das, was in All drin steht.

00:26:34.328 --> 00:26:39.948
Also Unterstrich, Unterstrich, All, Unterstrich, Unterstrich, um es jetzt mal hier korrekt zu sagen.

00:26:40.268 --> 00:26:41.048
Dann, dann, All, dann, dann.

00:26:41.048 --> 00:27:04.008
Das ist ein sehr guter Mechanismus, den sieht man sehr selten, weil Importsternen ja so verpönt ist, so gerne gesehen wird. Das hatten wir schon in der ersten Vorlesung quasi in Informatik 1, hat uns unser Professor schon gesagt, ja man kann using namespace standard nehmen und dann kann man mal gucken, wie viele Symbole da importiert werden und es waren irgendwie 13.000 oder sowas.

00:27:04.008 --> 00:27:06.728
und das kannst du in Python natürlich auch machen,

00:27:06.867 --> 00:27:08.688
kannst auch from Stern import Stern

00:27:08.688 --> 00:27:10.028
probieren,

00:27:10.367 --> 00:27:12.088
kriegst halt auch 100.000 Sachen rein.

00:27:13.208 --> 00:27:13.728
Deshalb ist

00:27:13.728 --> 00:27:15.048
import Stern,

00:27:15.108 --> 00:27:17.828
nee, nee, from Stern import Stern geht nicht,

00:27:17.948 --> 00:27:20.048
aber so quasi, wenn du es dir

00:27:20.048 --> 00:27:21.908
vorstellst. Import Stern heißt halt,

00:27:21.968 --> 00:27:24.088
hol alles aus diesem Modul oder aus dem Package

00:27:24.088 --> 00:27:25.388
und gib es mir

00:27:25.388 --> 00:27:27.468
und meistens weiß man ja gar nicht

00:27:27.468 --> 00:27:29.728
ganz genau, was da drin ist. Meistens weiß man auch nicht,

00:27:29.808 --> 00:27:30.768
wie viel da drin ist.

00:27:31.627 --> 00:27:33.888
Und ganz oft sind da ja dann

00:27:33.888 --> 00:27:35.888
auch lokale Sachen drin, die man eigentlich gar nicht haben

00:27:35.888 --> 00:27:37.948
möchte. Oder Imports, die

00:27:37.948 --> 00:27:39.867
dieses Modul macht,

00:27:39.928 --> 00:27:41.867
die hast du dann auf einmal auch selber

00:27:41.867 --> 00:27:43.688
importiert. Subdependencies quasi.

00:27:44.008 --> 00:27:45.828
Genau, also wenn du in

00:27:45.828 --> 00:27:47.748
der m.py, so wie wir es jetzt eben

00:27:47.748 --> 00:27:49.008
drin hatten,

00:27:49.688 --> 00:27:51.748
wenn du da import, keine Ahnung, import

00:27:51.748 --> 00:27:53.648
x machst, und dann machst du from m

00:27:53.648 --> 00:27:55.808
import Stern, hast du auch x importiert.

00:27:56.528 --> 00:27:57.808
Weil das halt in dem

00:27:57.808 --> 00:27:59.788
Modul m dann schon drin ist. Und das ist genau

00:27:59.788 --> 00:28:01.688
der Grund, warum man dieses Stern nicht machen soll, weil man nämlich

00:28:01.688 --> 00:28:03.408
nicht weiß, was da drin ist und man halt dann alle...

00:28:03.408 --> 00:28:05.648
schon gab, bei einem Lokal irgendwo

00:28:05.648 --> 00:28:07.448
überschreiben würde. Und wenn mehrere

00:28:07.448 --> 00:28:09.468
Module oder Pakete

00:28:09.468 --> 00:28:11.828
dasselbe Namen definieren

00:28:11.828 --> 00:28:13.328
für irgendwas, was ja durchaus mal vorkommen kann,

00:28:13.488 --> 00:28:15.428
dann weiß man nicht mehr genau, was unter dem Namen jeweils

00:28:15.428 --> 00:28:17.488
Identität ist. Aber jetzt müssen wir ja erstmal klären,

00:28:17.568 --> 00:28:19.568
was Import überhaupt macht. Wir sprechen

00:28:19.568 --> 00:28:21.288
jetzt schon die ganze Zeit so, aber wir wissen es immer noch nicht.

00:28:21.288 --> 00:28:23.768
Wir wissen aber immer noch nicht genau, was ein Modul, ein Paket ist.

00:28:24.968 --> 00:28:25.488
Ja, also ich glaube,

00:28:25.548 --> 00:28:26.988
das eine ist eine Datei und das andere ist

00:28:26.988 --> 00:28:28.248
ein Verzeichnis.

00:28:29.028 --> 00:28:30.108
Es gibt eine Datei.

00:28:30.108 --> 00:28:31.248
Ich glaube, es ist auch irgendwie...

00:28:31.248 --> 00:28:31.748
der Datei.

00:28:32.988 --> 00:28:34.968
Ich glaube, der entscheidende Unterschied ist, dass

00:28:34.968 --> 00:28:36.988
ein Paket Submodule haben kann

00:28:36.988 --> 00:28:38.468
und ein Modul nicht.

00:28:39.568 --> 00:28:41.148
Also genau, ich habe

00:28:41.148 --> 00:28:42.048
eine Definition gefunden,

00:28:42.347 --> 00:28:44.968
der irgendwo sagt hat, if a module name

00:28:44.968 --> 00:28:47.028
has no dots, it's not considered to be part

00:28:47.028 --> 00:28:47.508
of a package.

00:28:48.808 --> 00:28:48.948
Aha.

00:28:51.168 --> 00:28:51.928
Ja, okay.

00:28:52.388 --> 00:28:54.768
Also ein Paket ist

00:28:54.768 --> 00:28:56.948
quasi eine Sammlung von Modulen oder sowas?

00:28:58.127 --> 00:28:58.668
Ja, okay, gut.

00:28:59.928 --> 00:29:00.048
Ja.

00:29:00.048 --> 00:29:03.828
Da gab es auch eine tolle Antwort drin, Relative Imports for the Billions Times oder sowas.

00:29:04.048 --> 00:29:11.208
Ja, relative Imports, darüber muss man auch noch sprechen. Ich bin ein großer Fan davon, aber offensichtlich nicht so. Gut, da kommen wir vielleicht nach.

00:29:11.208 --> 00:29:12.107
Ja, ja, ja, okay.

00:29:13.228 --> 00:29:19.548
Also was macht denn Import jetzt überhaupt? Import macht, soll ich mal versuchen, soll ich mal mein Verständnis erklären und er korrigiert mich dann.

00:29:20.627 --> 00:29:21.708
Von wo importiert ihr denn überhaupt?

00:29:21.708 --> 00:29:35.847
Genau, also Import. Erstmal sucht Import ein, also wenn ich sage Import M, dann sucht das Import-System von Python nach etwas, das M heißt. Und zwar auf dem Python Path.

00:29:35.847 --> 00:29:37.248
Auf dem Python Path. Ah.

00:29:37.248 --> 00:29:38.468
eine Variable, die heißt

00:29:38.468 --> 00:29:40.168
sys.pythonpath

00:29:40.168 --> 00:29:42.908
sys.path heißt die, oder?

00:29:43.028 --> 00:29:45.228
Ich weiß, ich vergesse es jetzt mal wieder.

00:29:46.188 --> 00:29:47.388
Jedenfalls ist da eine Menge

00:29:47.388 --> 00:29:49.248
von Verzeichnissen drin und

00:29:49.248 --> 00:29:51.168
in der Reihenfolge, wie sie in diesem

00:29:51.168 --> 00:29:53.388
Path stehen, wird nach

00:29:53.388 --> 00:29:55.328
dem Namen

00:29:55.328 --> 00:29:57.328
M gesucht. Also 0 ist glaube ich der aktuelle

00:29:57.328 --> 00:29:58.367
irgendwie, dass das

00:29:58.367 --> 00:30:01.127
entweder vorne oder hinten, das ist immer

00:30:01.127 --> 00:30:03.528
Ich glaube 0, der erste ist immer der, wo du gerade bist.

00:30:03.528 --> 00:30:04.508
Punkt. Genau.

00:30:04.508 --> 00:30:06.748
also die Datei, wo du gerade aufgeführt bist

00:30:06.748 --> 00:30:08.448
oder sowas und dann ist halt quasi, der sucht halt dann

00:30:08.448 --> 00:30:10.328
im ersten in 1, wo und ab da

00:30:10.328 --> 00:30:12.748
und der erste Hit wird dann genommen

00:30:12.748 --> 00:30:14.548
Genau, der erste Hit wird dann genommen und in diesem Path

00:30:14.548 --> 00:30:16.748
können ganz viele verschiedene Sachen

00:30:16.748 --> 00:30:18.008
drin sein, also die Installation

00:30:18.008 --> 00:30:20.268
des Installationsverzeichnisses des Interpreters

00:30:20.268 --> 00:30:22.867
und wenn man irgendwelche

00:30:22.867 --> 00:30:24.768
Environments aktiviert hat, dann sind die da alle drin

00:30:24.768 --> 00:30:26.488
man kann da auch selber Sachen reintun

00:30:26.488 --> 00:30:28.908
braucht man manchmal, ist manchmal ganz nützlich

00:30:28.908 --> 00:30:32.828
Also wenn man verschiedene Pakete

00:30:32.828 --> 00:30:34.127
haben will, die auch importiert werden können

00:30:34.127 --> 00:30:35.988
dann muss man einfach da gucken, dass

00:30:35.988 --> 00:30:38.107
in this.path quasi in der Umgebungsvariante

00:30:38.107 --> 00:30:39.928
Das ist im Wesentlichen das, was

00:30:39.928 --> 00:30:42.068
VirtualEnv macht. Er macht ein Verzeichnis, wo

00:30:42.068 --> 00:30:43.928
du deine Pakete reinlegen kannst und tut den

00:30:43.928 --> 00:30:45.948
in den Python-Path für dich. Genau, das heißt, wichtig,

00:30:46.088 --> 00:30:48.107
dass euer Path vernünftig konfiguriert ist, wenn ihr Python nutzt,

00:30:48.448 --> 00:30:50.088
weil wenn die falsche Reihenfolge drin ist, dann kann

00:30:50.088 --> 00:30:51.488
das sein, dass er im Path von Python

00:30:51.488 --> 00:30:54.028
2 sucht oder so, also wie es

00:30:54.028 --> 00:30:56.088
früher offenbar war. Und dann habt ihr ein Problem.

00:30:56.528 --> 00:30:56.627
Genau.

00:30:58.188 --> 00:30:59.928
Also, und er sucht diese ganzen Verzeichnisse durch

00:30:59.928 --> 00:31:02.028
und wenn da irgendwas drin ist, was diesem Namen m entspricht,

00:31:02.028 --> 00:31:03.928
also eine m.py oder ein Verzeichnis, was m

00:31:03.928 --> 00:31:05.847
heißt, was eine InitPy hat, oder

00:31:05.847 --> 00:31:08.048
in Python 3 ein Verzeichnis, was

00:31:08.048 --> 00:31:10.288
das M heißt und Python-Dateien

00:31:10.288 --> 00:31:11.788
enthält, was keine InitPy hat,

00:31:12.607 --> 00:31:13.808
dann wird

00:31:13.808 --> 00:31:15.908
das als Modul importiert

00:31:15.908 --> 00:31:18.048
und in den aktuellen Namespace

00:31:18.048 --> 00:31:19.867
als Modul M übergeben.

00:31:20.088 --> 00:31:21.968
Wir haben gerade wirklich das schon in Python 2 und 3 diskriminiert,

00:31:22.008 --> 00:31:23.607
das ist ja interessant. Ja, da gibt es Unterschiede.

00:31:23.728 --> 00:31:25.948
Ja, da gibt es auch interessante,

00:31:26.088 --> 00:31:27.748
also nochmal ein sehr interessanter Unterschied

00:31:27.748 --> 00:31:29.928
kommt mit Python 3.3

00:31:29.928 --> 00:31:32.748
glaube ich dazu, nämlich die Namespace-Only-Pakete.

00:31:33.928 --> 00:31:34.568
Erklär mal.

00:31:36.107 --> 00:31:36.908
Die gibt es.

00:31:37.367 --> 00:31:39.347
Früher musste man ja immer die InitPUI haben.

00:31:40.367 --> 00:31:41.627
Vor allen Dingen deswegen,

00:31:41.808 --> 00:31:43.248
damit halt nicht Verzeichnisse,

00:31:43.627 --> 00:31:45.208
die halt so heißen wie ein Standardmodul,

00:31:45.288 --> 00:31:46.347
das Standardmodul überschreiben.

00:31:47.988 --> 00:31:49.548
Und man halt damit dann

00:31:49.548 --> 00:31:51.428
quasi öffentlich

00:31:51.428 --> 00:31:53.367
sich dazu bekennt, dass das jetzt ein

00:31:53.367 --> 00:31:54.308
Paket sein soll.

00:31:55.988 --> 00:31:57.768
Also sozusagen, wenn man sich den Infus

00:31:57.768 --> 00:31:59.367
schließt, dann muss man das auch wirklich absichtlich gemacht haben.

00:32:00.088 --> 00:32:01.548
Und das ist aber

00:32:01.548 --> 00:32:02.748
teilweise blöd.

00:32:03.928 --> 00:32:05.808
weil oft will man vielleicht auch

00:32:05.808 --> 00:32:07.867
Dinge, die in einem Paket liegen, nicht in einem

00:32:07.867 --> 00:32:08.968
Verzeichnis haben zum Beispiel.

00:32:09.908 --> 00:32:11.408
Und also wenn es

00:32:11.408 --> 00:32:13.448
ein InitPy gibt, dann

00:32:13.448 --> 00:32:14.988
ist das

00:32:14.988 --> 00:32:18.028
ja dann, jetzt weiß ich

00:32:18.028 --> 00:32:19.648
nicht mehr die Stelle, wo das irgendwo drin steht,

00:32:19.748 --> 00:32:21.448
dass da drin gesucht werden soll, also

00:32:21.448 --> 00:32:23.728
Dispass, ja, aber es gibt auch noch irgendwie

00:32:23.728 --> 00:32:25.788
andere Stellen, glaube ich. Es gibt auch noch Module,

00:32:25.908 --> 00:32:27.748
die nicht da drin sind, zum Beispiel die

00:32:27.748 --> 00:32:29.828
Standardbibliotheksmodule

00:32:29.828 --> 00:32:31.688
sind, also es gibt welche, die sind irgendwie in

00:32:31.688 --> 00:32:33.748
das Python-Binary reinkompiliert und dann gibt es

00:32:33.748 --> 00:32:34.988
auch noch welche, die sind irgendwie

00:32:34.988 --> 00:32:37.888
woanders hingemarschelt, aber die liegen da auch irgendwo rum.

00:32:38.688 --> 00:32:39.847
Also die Python-Module,

00:32:40.028 --> 00:32:40.607
die nicht zählen.

00:32:41.728 --> 00:32:43.828
Das stimmt, das kann man, aber es gibt auch noch

00:32:43.828 --> 00:32:45.488
Dinge, Module, die sind halt einfach nur

00:32:45.488 --> 00:32:47.828
in der Shared Library

00:32:47.828 --> 00:32:48.888
und nicht irgendwie Python.

00:32:49.988 --> 00:32:50.928
Aber da kommen wir gleich noch so,

00:32:51.068 --> 00:32:53.627
wo der Pycache und so weiter noch was, aber egal.

00:32:54.988 --> 00:32:55.347
Genau.

00:32:56.228 --> 00:32:57.867
Aber man kann halt auch,

00:32:58.088 --> 00:32:59.728
es gibt auch Verzeichnisse und denen wird

00:32:59.728 --> 00:33:01.347
auch gesucht, wenn da kein NPY ist,

00:33:01.347 --> 00:33:02.528
das ist allerdings dann irgendwie

00:33:02.528 --> 00:33:04.228
weiter hinten.

00:33:04.968 --> 00:33:06.808
Und alle, die den gleichen Namen haben,

00:33:06.988 --> 00:33:08.908
wenn da jetzt Sachen drin liegen, dann wird das

00:33:08.908 --> 00:33:11.068
zum gleichen Paket

00:33:11.068 --> 00:33:12.888
gehörig irgendwie aufgefasst

00:33:12.888 --> 00:33:15.408
und das ist dann so ein Namespace-Package.

00:33:15.548 --> 00:33:16.928
So ein Namespace-Mengeling.

00:33:17.168 --> 00:33:18.468
Und dann kannst du halt auch...

00:33:18.468 --> 00:33:20.708
Also wir halten fest, einfach immer eine Init-Pi.

00:33:21.228 --> 00:33:22.768
Ja, dann...

00:33:22.768 --> 00:33:25.088
Aber so kannst du

00:33:25.088 --> 00:33:27.008
halt auch Dinge in einem Paket haben, die in unterschiedlichen

00:33:27.008 --> 00:33:28.888
Verzeichnissen liegen, was halt manchmal auch ganz praktisch ist.

00:33:29.508 --> 00:33:29.728
Klar.

00:33:29.888 --> 00:33:31.528
Ja, okay.

00:33:32.528 --> 00:33:34.168
Okay.

00:33:34.788 --> 00:33:36.668
Was ist dann, das haben wir gesagt,

00:33:36.748 --> 00:33:38.428
Package, es gibt auch ein dann dann Package.

00:33:38.847 --> 00:33:39.708
Was steht denn da?

00:33:41.168 --> 00:33:42.328
Ist das Current Package?

00:33:42.627 --> 00:33:42.828
Genau.

00:33:44.468 --> 00:33:45.588
Das ist das aktuelle Paket.

00:33:45.808 --> 00:33:47.148
Das ist ein Top-Level-Modul oder sowas, ja?

00:33:48.127 --> 00:33:50.408
Ja, oh Gott, ich weiß auch nicht.

00:33:50.748 --> 00:33:52.408
Ich glaube, wenn es None ist, dann ist es ein Skript.

00:33:53.828 --> 00:33:54.668
Also vielleicht noch mal zu distinguieren,

00:33:54.768 --> 00:33:56.268
ist das ein Modul, ein Paket oder so?

00:33:56.268 --> 00:33:57.788
Wenn Package None ist, dann ist das nur ein Skript.

00:33:57.908 --> 00:33:59.828
Und wenn er sucht, dann auch, wer so ein Package findet.

00:33:59.908 --> 00:34:01.508
Und wenn er eins findet, dann ist das Top-Level-Modul,

00:34:01.508 --> 00:34:02.948
von dem man dann importieren kann oder so.

00:34:04.528 --> 00:34:05.648
Und wenn es das nicht gibt, dann gibt es halt auch

00:34:05.648 --> 00:34:07.648
Fehler. Attempted Relative Import

00:34:07.648 --> 00:34:08.688
Beyond Top Level Package.

00:34:09.328 --> 00:34:11.427
Ja, das ist

00:34:11.427 --> 00:34:12.907
so eine Sache, die gibt es.

00:34:15.067 --> 00:34:15.627
Passiert mir auch

00:34:15.627 --> 00:34:17.547
regelmäßig. Echt, das passiert mir nie, das ist

00:34:17.547 --> 00:34:19.887
voll seltsam. Doch, passiert mir auch. Es gibt so Sachen, die

00:34:19.887 --> 00:34:21.528
machen Menschen offensichtlich

00:34:21.528 --> 00:34:23.468
unterschiedlich und das ist so eine Sache, die mache ich offenbar nicht.

00:34:24.028 --> 00:34:25.488
Also nicht, weil ich besser bin oder

00:34:25.488 --> 00:34:27.547
weil ich irgendwie das toller kann oder so, sondern

00:34:27.547 --> 00:34:29.907
weil es einfach was ist, was ich nicht benutze.

00:34:29.907 --> 00:34:32.087
Ja gut, aber wenn du relative Importe benutzt, wie du gesagt hast.

00:34:32.087 --> 00:34:34.288
Die liebe ich. Relative Importe sind voll gut.

00:34:34.488 --> 00:34:35.448
Davon vertippt man sich ja mal.

00:34:35.887 --> 00:34:38.968
Also relative Importe, jetzt müssen wir über relative Importe sprechen.

00:34:39.188 --> 00:34:40.188
In Python 3

00:34:40.188 --> 00:34:42.627
und ich glaube in 2.7 wurde das dann

00:34:42.627 --> 00:34:44.907
irgendwann geportet, gibt es die Möglichkeit zu sagen

00:34:44.907 --> 00:34:46.488
from .import irgendwas.

00:34:46.748 --> 00:34:47.828
Also from .import m.

00:34:47.988 --> 00:34:48.648
Oder vom .dot.

00:34:50.347 --> 00:34:53.127
Oder auch from .m

00:34:53.127 --> 00:34:54.288
import irgendwas.

00:34:54.948 --> 00:34:56.448
Und dieser Punkt heißt halt eben immer

00:34:56.448 --> 00:34:58.047
aktuelles Verzeichnis.

00:34:58.047 --> 00:34:59.808
also aktueller

00:34:59.808 --> 00:35:00.948
Pfad.

00:35:02.008 --> 00:35:04.107
Das heißt, wenn es in dieser

00:35:04.107 --> 00:35:05.908
Installation, die ich habe, zwei Module gibt, die

00:35:05.908 --> 00:35:07.928
M heißen, dann kann ich durch

00:35:07.928 --> 00:35:09.847
diesen relativen Import genauer sagen,

00:35:09.928 --> 00:35:10.627
welches ich meine.

00:35:11.168 --> 00:35:13.728
Ach, okay, doch, nee, das war der Unterschied zwischen Modulen

00:35:13.728 --> 00:35:15.668
und Packages.

00:35:16.107 --> 00:35:17.168
Module haben einen Pfad dran.

00:35:18.107 --> 00:35:19.948
Ich glaube tatsächlich, das ist der entscheidende Unterschied.

00:35:20.828 --> 00:35:21.388
Ich glaube schon, ja.

00:35:23.087 --> 00:35:24.428
Genau, die Top-Level-Package

00:35:24.428 --> 00:35:25.288
ist halt irgendwie doch die Sache.

00:35:25.288 --> 00:35:27.607
Also wenn man ein Paket finden kann,

00:35:27.607 --> 00:35:29.668
also ein Top-Level finden kann mit diesem Dot-Dot,

00:35:29.728 --> 00:35:31.508
dann geht das halt. Aber wenn das None ist,

00:35:31.567 --> 00:35:33.547
weil man quasi auf der höchsten Ebene ist, dann gibt es halt Fehler zurück.

00:35:33.748 --> 00:35:35.008
Und das ist ja genau der Grund, warum...

00:35:35.008 --> 00:35:37.528
Das kann natürlich sein, dass ich das einfach nie...

00:35:37.528 --> 00:35:39.008
Also für mich ist einfach Punkt, ja.

00:35:39.248 --> 00:35:41.168
Wenn ich sage from Punkt importen, dann weiß ich,

00:35:41.228 --> 00:35:42.627
das muss im aktuellen Verzeichnis liegen.

00:35:43.168 --> 00:35:44.828
Wenn ich sage from Punkt Punkt, dann weiß ich,

00:35:44.888 --> 00:35:46.328
das muss im Verzeichnis drüber liegen.

00:35:46.808 --> 00:35:48.508
Und für mich ist das einfach eine Möglichkeit,

00:35:48.828 --> 00:35:50.708
quasi in meinem Projekt zu navigieren.

00:35:51.748 --> 00:35:53.468
Also ich sag mal so, das geht aber nur dann,

00:35:53.587 --> 00:35:54.828
wenn der Interpreter richtig aufgelöst ist,

00:35:54.828 --> 00:35:57.047
weil wenn du tief drin bist und dann das Skript

00:35:57.047 --> 00:35:58.268
beispielsweise manuell ausführt,

00:35:58.347 --> 00:36:00.508
relativ tief drin, dann wird der ja diesen Fehler schmeißen.

00:36:00.648 --> 00:36:02.748
Wenn du diese Datei direkt

00:36:02.748 --> 00:36:04.708
aufrufst. Das kann man übrigens verhindern,

00:36:04.768 --> 00:36:06.228
indem man einfach sagt, Python-m

00:36:06.228 --> 00:36:08.668
und dann dieses Modul dann innerhalb

00:36:08.668 --> 00:36:09.288
von dem Pfad aufrufen.

00:36:10.047 --> 00:36:12.448
Die meisten meiner Projekte sind ja bei einem Django-Umfeld.

00:36:12.888 --> 00:36:14.607
Und da bin ich nie in der Verlegenheit,

00:36:14.708 --> 00:36:16.648
diese Sachen direkt aufzurufen, sondern die werden dann

00:36:16.648 --> 00:36:18.847
entweder über einen Run-Server

00:36:18.847 --> 00:36:20.508
aufgerufen oder über einen Test oder

00:36:20.508 --> 00:36:22.668
über einen Command.

00:36:22.847 --> 00:36:24.808
Auch da ist der Pfad, musst du ja

00:36:24.808 --> 00:36:26.668
richtig definieren. Ja, aber der Pfad ist

00:36:26.668 --> 00:36:28.248
immer festgemacht an der Managed-Py.

00:36:28.587 --> 00:36:30.928
Genau. Das heißt, das weiß ich.

00:36:30.988 --> 00:36:32.367
Ich weiß, wo der Pfad...

00:36:32.367 --> 00:36:34.488
Ja, aber das ist ja auch Python-USM-Package.module oder so.

00:36:34.888 --> 00:36:36.627
Genau. Und deshalb ist das vielleicht

00:36:36.627 --> 00:36:38.587
was, was einfach in meiner täglichen

00:36:38.587 --> 00:36:39.968
Arbeit nicht so auftritt, dass ich da

00:36:39.968 --> 00:36:42.268
mich quasi vernavigiere,

00:36:42.627 --> 00:36:44.448
weil meine Projekte eben immer

00:36:44.448 --> 00:36:46.528
eine feste Wurzel

00:36:46.528 --> 00:36:48.008
haben und darunter kann ich

00:36:48.008 --> 00:36:49.488
mich bewegen, wie ich möchte.

00:36:50.847 --> 00:36:52.668
Ja, mir passiert das halt vor allen Dingen dann,

00:36:52.668 --> 00:36:54.908
also einmal, in Paketen

00:36:54.908 --> 00:36:56.607
habe ich oft gerne Tests und in anderen

00:36:56.607 --> 00:37:00.607
Verzeichnis. Also da gibt es halt Test nicht innerhalb von dem Projekt selber,

00:37:00.748 --> 00:37:04.587
sondern liegen halt in einem Test Directory. Wenn da irgendwas nicht richtig konfiguriert ist, dann passiert das halt

00:37:04.587 --> 00:37:08.268
schon mal. Und was mir halt auch ab und zu passiert ist,

00:37:08.607 --> 00:37:12.328
in Jupyter Notebooks, weil die liegen halt auch wieder in einem anderen Verzeichnis.

00:37:12.328 --> 00:37:16.348
Und die sind halt auch irgendwo. Genau. Und deswegen sehe ich das halt

00:37:16.348 --> 00:37:20.408
häufiger mal. Bei diesem Import auch ganz interessant. Ich glaube, das kommt dann wirklich darauf an, wenn der Name

00:37:20.408 --> 00:37:22.768
des Moduls Punkte enthält oder halt nicht.

00:37:22.768 --> 00:37:25.087
weil wenn er Punkte hat, dann

00:37:25.087 --> 00:37:26.968
Achso, wenn der Name des Moduls, also wenn das

00:37:26.968 --> 00:37:30.087
Modul quasi m.x.y

00:37:30.087 --> 00:37:31.328
Genau, dann ist es halt

00:37:31.328 --> 00:37:33.087
ein paar Reihenverkehrs

00:37:33.087 --> 00:37:34.248
und wenn es halt

00:37:34.248 --> 00:37:37.288
wenn es halt keinen Punkt mehr hat

00:37:37.288 --> 00:37:38.908
dann muss es eigentlich schon

00:37:38.908 --> 00:37:41.308
Top-Level sein, weil dann kannst du nicht

00:37:41.308 --> 00:37:47.288
Aber man kann ja jetzt auch so Dinge tun wie

00:37:47.288 --> 00:37:47.788
man sagt

00:37:47.788 --> 00:37:50.248
from m import

00:37:50.248 --> 00:37:52.027
x oder so

00:37:52.027 --> 00:37:53.988
und was mit Wings dann. Habt ihr schon mal Skriptnamen mit

00:37:53.988 --> 00:37:55.607
Punkten verwendet? Also mit mehreren Punkten drin?

00:37:55.607 --> 00:37:57.728
Nee, das hab ich gerade jetzt überlegt, ob ich

00:37:57.728 --> 00:37:59.408
eine Datei mit

00:37:59.408 --> 00:38:01.627
Punkten drin hätte, ohne also Punkt

00:38:01.627 --> 00:38:03.007
Py. Ich glaube, dass das

00:38:03.007 --> 00:38:05.587
zu Problemen führt, oder? Ich glaube auch, dass das zu Problemen

00:38:05.587 --> 00:38:07.607
führt und das würde ich auch vermeiden einfach.

00:38:08.848 --> 00:38:09.908
Ja, interessant.

00:38:10.388 --> 00:38:11.468
Stimmt, das hab ich auch noch nicht.

00:38:12.127 --> 00:38:13.648
Das müssen wir, das wird dann die nächste

00:38:13.648 --> 00:38:15.448
Episode. Was passiert eigentlich, wenn wir Punkt 1

00:38:15.448 --> 00:38:17.627
geben? Ja, genau.

00:38:17.848 --> 00:38:19.668
Achso, genau, die Form

00:38:19.668 --> 00:38:21.668
import m ist ja

00:38:21.668 --> 00:38:23.968
noch vergleichsweise offensichtlich. Aber jetzt hat der Jochen eben gesagt,

00:38:24.007 --> 00:38:25.428
was ist denn, wenn ich sage, from m import x?

00:38:25.428 --> 00:38:25.808
Genau.

00:38:27.488 --> 00:38:29.748
Und was dann halt für mich passiert ist,

00:38:30.208 --> 00:38:31.228
er importiert erst m

00:38:31.228 --> 00:38:33.368
und guckt dann

00:38:33.368 --> 00:38:35.567
in m nach, ob es da etwas gibt, was x heißt

00:38:35.567 --> 00:38:37.107
und gibt mir das als Import.

00:38:37.828 --> 00:38:38.948
Aber das stimmt nicht ganz.

00:38:40.087 --> 00:38:41.288
Weil es kann nämlich auch,

00:38:41.507 --> 00:38:43.348
man kann auch from m import x machen,

00:38:43.468 --> 00:38:44.688
wenn es in m gar kein x gibt.

00:38:46.428 --> 00:38:47.228
Weil eben,

00:38:47.748 --> 00:38:49.348
wie angekündigt,

00:38:50.107 --> 00:38:51.268
wenn m eine

00:38:51.268 --> 00:38:53.007
Verzeichnis ist, was eine InitPy enthält.

00:38:53.948 --> 00:38:55.448
Dann kriege ich aus dem

00:38:55.448 --> 00:38:57.228
Import M alles das raus, was in der InitPy

00:38:57.228 --> 00:38:59.107
drin ist. Aber from M

00:38:59.107 --> 00:39:01.127
Import X kann dann die Datei X.py sein.

00:39:01.448 --> 00:39:03.208
Also M-X.py

00:39:03.208 --> 00:39:04.547
und die kann ich mit,

00:39:05.288 --> 00:39:06.248
also an die komme ich dran,

00:39:06.567 --> 00:39:09.107
aber die ist nicht

00:39:09.107 --> 00:39:11.047
in M selbst enthalten. Also wenn ich nur Import M mache,

00:39:11.107 --> 00:39:11.888
gibt es nicht M.x.

00:39:12.828 --> 00:39:14.888
Kann so sein. Deshalb

00:39:14.888 --> 00:39:16.968
ist es dann doch

00:39:16.968 --> 00:39:19.148
immer noch ein kleines bisschen

00:39:19.148 --> 00:39:20.748
anders. Also man muss eigentlich immer auf die Datei

00:39:20.748 --> 00:39:21.888
zeigen, die wir haben.

00:39:21.988 --> 00:39:24.488
Ja, genau, das hat mich auch überrascht.

00:39:24.567 --> 00:39:25.948
Das wusste ich nicht, wenn man sagt,

00:39:26.027 --> 00:39:28.627
import x, ich weiß nicht, was ich vorher gedacht habe,

00:39:28.908 --> 00:39:30.668
aber ich dachte, das holt das x da raus

00:39:30.668 --> 00:39:32.228
und dann hat man das halt im eigenen Namespace.

00:39:32.648 --> 00:39:34.688
Aber eben, es macht halt eher sowas wie import m,

00:39:35.007 --> 00:39:36.788
dann sagt es x gleich m.x

00:39:36.788 --> 00:39:37.888
und dann sagt es del m.

00:39:38.928 --> 00:39:40.788
Und das ist halt eher so das, was tatsächlich passiert.

00:39:40.788 --> 00:39:43.288
Und das ist auch schon so, ui, ui, okay.

00:39:43.908 --> 00:39:44.828
Also wenn es nicht geht, macht er doch was anderes.

00:39:45.127 --> 00:39:46.288
Dann holt er sich doch noch die Detail.

00:39:46.768 --> 00:39:47.288
Ja, ja, ja.

00:39:47.288 --> 00:39:48.107
Also

00:39:48.107 --> 00:39:51.188
es ist natürlich alles übrigens noch gecached.

00:39:51.408 --> 00:39:53.328
Man kann so oft import m machen, wie man möchte.

00:39:53.448 --> 00:39:54.968
Es wird nur einmal gelesen, die Datei.

00:39:55.308 --> 00:39:56.908
Und wo wird das dann reingeschrieben?

00:39:57.027 --> 00:39:59.408
In das Dictionary der offenen

00:39:59.408 --> 00:40:00.928
Module?

00:40:00.928 --> 00:40:02.127
In das Dictionary der geladenen Module.

00:40:02.308 --> 00:40:04.348
Das heißt irgendwie sys.modules.

00:40:04.488 --> 00:40:05.188
Ja, weiß ich auch nicht.

00:40:07.027 --> 00:40:08.728
Keine Ahnung.

00:40:08.908 --> 00:40:09.547
Das heißt sys.modules.

00:40:11.328 --> 00:40:21.695
Dominik wei es Das ist auch so eine Geschichte das kann man auch sch verwenden Manchmal braucht man ja also Singleton ein ehrlich gesagt

00:40:23.035 --> 00:40:25.675
Es hat einen total coolen Namen,

00:40:25.795 --> 00:40:26.955
deswegen wollen es die Leute immer verwenden.

00:40:27.935 --> 00:40:28.835
Manchmal braucht man das.

00:40:28.975 --> 00:40:30.455
Manchmal braucht man es tatsächlich,

00:40:30.715 --> 00:40:32.715
meistens eher nicht.

00:40:32.815 --> 00:40:34.355
Aber Module sind immer Singletons.

00:40:34.575 --> 00:40:37.375
Ganz genau. Und das ist tatsächlich die eleganteste Art,

00:40:37.475 --> 00:40:38.375
die ich kenne, wie man das macht.

00:40:38.375 --> 00:40:39.735
Und es ist auch manchmal total nervig.

00:40:39.735 --> 00:40:41.255
Ja, aber

00:40:41.255 --> 00:40:44.555
ich habe da vorher schon

00:40:44.555 --> 00:40:46.375
also meistens habe ich dann Borg-Pattern verwendet

00:40:46.375 --> 00:40:47.955
oder halt irgendwas in der Richtung

00:40:47.955 --> 00:40:50.455
oder manchmal halt auch, wenn ich nicht Borg wollte

00:40:50.455 --> 00:40:52.615
sondern direkt Singleton, dann wurde es aber schon hakelig

00:40:52.615 --> 00:40:54.455
dann muss man schon

00:40:54.455 --> 00:40:56.175
so Meta-Klassen oder sonst irgendwie sowas

00:40:56.175 --> 00:40:58.435
so Dinge, wo man sich hinterher schon ein bisschen schmutzig

00:40:58.435 --> 00:41:00.175
fühlt, irgendwie machen und

00:41:00.175 --> 00:41:02.255
bis ich dann irgendwann mal, weiß ich gar nicht, wo ich das gesehen habe

00:41:02.255 --> 00:41:04.295
den Trick, so dass jemand meinte, ja ja, Module sind doch sowieso

00:41:04.295 --> 00:41:06.315
Singleton, es sind doch einfach globale Variablen

00:41:06.315 --> 00:41:06.795
in einem Modul

00:41:06.795 --> 00:41:09.175
Ja, stimmt ja

00:41:09.175 --> 00:41:09.715
Stimmt.

00:41:10.195 --> 00:41:13.015
Das muss man ja nochmal genau erklären, warum das ein Singleton ist.

00:41:13.175 --> 00:41:15.395
Aber Jochen, wenn du dann das Pattern richtig ausführen

00:41:15.395 --> 00:41:17.115
musst, musst du dann noch in dem Modul noch ein

00:41:17.115 --> 00:41:19.235
Get irgendwas

00:41:19.235 --> 00:41:19.595
machen.

00:41:19.595 --> 00:41:19.935
Ja, ja.

00:41:20.135 --> 00:41:24.595
Falls jemand versucht,

00:41:24.935 --> 00:41:25.815
drumherum zu kommen.

00:41:26.075 --> 00:41:27.255
Ja, genau. Eigentlich ja.

00:41:28.915 --> 00:41:29.615
Jetzt der Dominik

00:41:29.615 --> 00:41:30.835
möchte es gerne erklärt haben.

00:41:31.075 --> 00:41:33.535
Also ein Singleton macht irgendwie,

00:41:33.735 --> 00:41:35.515
dass er guckt, ob es schon ein Objekt gibt,

00:41:35.775 --> 00:41:37.595
das dieses Typen ist und gibt das

00:41:37.595 --> 00:41:39.675
zurück, wenn es schon gibt, und schert einfach das eine,

00:41:39.755 --> 00:41:41.515
was es nur geben darf. Ja, Singleton heißt ja erstmal

00:41:41.515 --> 00:41:43.375
nur, es gibt während der Ausführung des

00:41:43.375 --> 00:41:44.715
Programms nur eins davon.

00:41:45.655 --> 00:41:46.835
Egal, was davon ist.

00:41:47.095 --> 00:41:49.495
Und Borg ist, dass es gibt ganz viele davon, aber die sind

00:41:49.495 --> 00:41:51.595
alle dieselben Eigenschaften.

00:41:53.315 --> 00:41:55.335
Ja, da wird der State

00:41:55.335 --> 00:41:57.615
geshared, aber es ist nicht die gleiche Instanz

00:41:57.615 --> 00:41:59.595
tatsächlich. Es können unterschiedliche Instanzen

00:41:59.595 --> 00:42:01.375
sein, aber der State ist immer der gleiche. Genau, das heißt,

00:42:01.415 --> 00:42:03.175
die Eigenschaften sind alle dieselben über alle Instanzen hinweg.

00:42:03.375 --> 00:42:04.095
Ja, genau.

00:42:05.555 --> 00:42:07.315
Und Singleton kriegt man eben durch

00:42:07.315 --> 00:42:09.175
Modul einfach hin. Also ich mache eine Datei

00:42:09.175 --> 00:42:10.475
singleton.py

00:42:10.475 --> 00:42:12.715
und da schreibe ich rein x gleich 2.

00:42:13.795 --> 00:42:14.975
Dann mache ich import singleton

00:42:14.975 --> 00:42:16.395
und dann sage ich singleton.x

00:42:16.395 --> 00:42:19.095
und das ist jetzt diese

00:42:19.095 --> 00:42:21.155
Instanz, dieses .x

00:42:21.155 --> 00:42:23.015
gibt es nur genau einmal, weil der

00:42:23.015 --> 00:42:25.315
Python Interpreter eben beim Import

00:42:25.315 --> 00:42:27.255
jede Datei

00:42:27.255 --> 00:42:28.895
nur einmal importiert, um es mal so zu sagen.

00:42:29.135 --> 00:42:31.175
Wenn eine Datei einmal importiert wurde,

00:42:31.415 --> 00:42:33.035
dann liegt die im Cache und dann

00:42:33.035 --> 00:42:35.075
wenn du dann import singleton sagst, kriegst du wieder

00:42:35.075 --> 00:42:35.635
die aus dem Cache.

00:42:35.635 --> 00:42:38.395
mit allen ihren Eigenschaften.

00:42:39.015 --> 00:42:39.255
Das heißt,

00:42:40.255 --> 00:42:42.895
du kriegst es mit dem...

00:42:42.895 --> 00:42:44.075
Du kannst es nicht ganz

00:42:44.075 --> 00:42:45.955
einfach machen, dass du diese Datei nochmal

00:42:45.955 --> 00:42:48.095
importierst, weil Python halt sagt,

00:42:48.135 --> 00:42:50.095
ja, die kenne ich ja schon. Brauche ich nicht nochmal

00:42:50.095 --> 00:42:50.515
importieren.

00:42:51.395 --> 00:42:53.635
Weil dieser Import,

00:42:53.635 --> 00:42:55.615
was ist das? Ein Modultyp dann,

00:42:55.655 --> 00:42:57.355
wenn du ein Modul hast? Genau, das heißt Modul.

00:42:57.955 --> 00:42:59.655
Und dieser Modultyp ist einfach

00:42:59.655 --> 00:43:01.995
eine Detailkette, keine Ahnung, von dem...

00:43:01.995 --> 00:43:03.475
Ja, das Ausgeführte.

00:43:03.555 --> 00:43:05.375
Das ist eigentlich der ausgeführte Code, der da drin ist.

00:43:05.635 --> 00:43:07.475
so einer Closure, die außen rum...

00:43:07.475 --> 00:43:09.595
Aber das wird dann doch gecastet,

00:43:09.675 --> 00:43:11.975
was dann Eval wäre, oder das habe ich dann nicht genau...

00:43:11.975 --> 00:43:13.735
Ja, im Endeffekt macht es ein Eval,

00:43:13.855 --> 00:43:15.755
aber halt ein

00:43:15.755 --> 00:43:17.375
sehr gut verstecktes.

00:43:19.075 --> 00:43:19.755
Ja gut, ich meine,

00:43:20.095 --> 00:43:21.755
Import heißt, führ mal bitte den Code

00:43:21.755 --> 00:43:23.575
in der Datei XYZ aus, also

00:43:23.575 --> 00:43:25.655
musst du ihn irgendwie ausführen. Irgendwo muss da ein Eval

00:43:25.655 --> 00:43:26.015
drin sein.

00:43:28.175 --> 00:43:29.695
Aber es ist eben hinter so vielen Schichten

00:43:29.695 --> 00:43:31.655
versteckt, dass du es nicht siehst. Also was der macht, ist,

00:43:31.655 --> 00:43:33.615
er lädt diese Datei... Immer wieder und immer wieder.

00:43:34.295 --> 00:43:35.275
Das heißt, wenn ich auch von mehreren...

00:43:35.275 --> 00:43:37.315
letzte einmal. Aber wenn ich an mehreren Stellen das habe,

00:43:37.375 --> 00:43:37.995
was ist denn dann passiert?

00:43:38.535 --> 00:43:41.135
Beim ersten Import Singleton wird diese

00:43:41.135 --> 00:43:43.255
Datei geladen und ausgeführt und

00:43:43.255 --> 00:43:45.175
das Ergebnis dieser Ausführung wird als

00:43:45.175 --> 00:43:46.235
Module Singleton

00:43:46.235 --> 00:43:49.415
abgelegt in diesem SysModulesCache.

00:43:49.575 --> 00:43:51.055
Und vielleicht wird dann da PyCache

00:43:51.055 --> 00:43:52.475
rausgebracht, PyC-Files oder so?

00:43:53.255 --> 00:43:55.415
Ja, nee, das ist nur eine interne

00:43:55.415 --> 00:43:57.135
Repräsentation. Das ist halt eben ein

00:43:57.135 --> 00:43:59.155
internes, das ist eine Klasse, die heißt

00:43:59.155 --> 00:44:00.635
Module und die hat Eigenschaften.

00:44:00.635 --> 00:44:00.815
Ja.

00:44:01.895 --> 00:44:04.555
Und wenn du dann nochmal Import Singleton

00:44:04.555 --> 00:44:06.095
machst, zum Beispiel in einer Datei oder

00:44:06.095 --> 00:44:08.535
zu einem späteren Zeitpunkt oder in einer Schleife, wo du es

00:44:08.535 --> 00:44:10.635
tausendmal machst, dann wird

00:44:10.635 --> 00:44:12.555
nicht nochmal diese Datei singleton.py

00:44:12.555 --> 00:44:14.195
geladen, sondern dann guckt er eben in seinen

00:44:14.195 --> 00:44:16.615
Sysmodules Cache und sagt, ah ja, den Namen singleton kenne ich schon.

00:44:16.775 --> 00:44:18.795
Genau, also beim ersten Import

00:44:18.795 --> 00:44:20.635
lädt er das tatsächlich in den Pycify

00:44:20.635 --> 00:44:22.475
rein, also das heißt, er macht aus Bytecode draus,

00:44:22.835 --> 00:44:23.975
er komponiert das quasi und

00:44:23.975 --> 00:44:25.955
er liest das quasi einmal aus,

00:44:25.955 --> 00:44:27.435
und man kippt das aus,

00:44:27.615 --> 00:44:29.695
macht dann Bytecode draus und dann schreibt er das

00:44:29.695 --> 00:44:31.655
in Pycache rein und von da versucht er dann

00:44:31.655 --> 00:44:32.995
erstmal zu laden aus Pyc.

00:44:32.995 --> 00:45:02.975
Genau.

00:45:02.995 --> 00:45:05.035
und dann ist dieser Code nicht mehr da.

00:45:05.215 --> 00:45:06.175
Es ist nur noch das Ergebnis da.

00:45:06.815 --> 00:45:09.035
Das Ergebnis der Ausführung dieser Datei

00:45:09.035 --> 00:45:10.975
ist dann das, was in das Modul reicht.

00:45:10.995 --> 00:45:12.895
Und was wird dann in die PyC-File reingeschrieben?

00:45:13.315 --> 00:45:15.295
Die PyC-Files sind so eine

00:45:15.295 --> 00:45:16.875
zwischendurch Optimierung, weil

00:45:16.875 --> 00:45:17.255
die

00:45:17.255 --> 00:45:21.055
enthalten so einen vorkompilierten Bytecode

00:45:21.055 --> 00:45:23.015
und der ist schneller zu laden als eine

00:45:23.015 --> 00:45:25.055
.py-Datei. Und das ist ein

00:45:25.055 --> 00:45:26.995
Marschalt-Objekt. Also wir hatten die ganz am Anfang

00:45:26.995 --> 00:45:28.695
einmal kurz Marschalt gesagt. Was ist das überhaupt?

00:45:28.815 --> 00:45:30.255
Einmal kurz nochmal den kleinen Exkurs.

00:45:30.695 --> 00:45:31.975
Jochen, erklär du doch mal.

00:45:31.975 --> 00:45:57.275
Ach ja, damals. Genau, im Grunde Marschaling ist eigentlich ein anderes Wort oder ist eines der Worte, die man benutzt, wenn man jetzt zum Beispiel Code oder irgendwie eine Datenstruktur serialisieren möchte in eine Liste von Buchstaben oder in einen String oder in eine Byte-Datenstruktur, die man dann halt irgendwie auf einer Platte speichern kann oder mit sich rumtragen.

00:45:57.275 --> 00:46:01.335
und genau, und da gab es zwei Module, die ersten waren halt Marshall,

00:46:01.575 --> 00:46:03.475
das heißt auch so, das gibt es immer noch in der Standardbibliothek,

00:46:03.815 --> 00:46:06.455
und Shelf, Shelf war schon damals nicht so richtig populär,

00:46:06.595 --> 00:46:10.715
also Marshall kann man immer noch verwenden, kann halt nur relativ wenige Datentypen

00:46:10.715 --> 00:46:15.475
und in neueren Python-Versionen verwendet man da eigentlich immer Pickle für,

00:46:15.535 --> 00:46:17.415
aber das ist halt im Grunde das, was es macht, wenn man sagt,

00:46:17.975 --> 00:46:23.855
vom Pickle, oder wenn man sagt cpickle.dump, dump-s oder so,

00:46:23.895 --> 00:46:26.015
dann wird das halt in String oder dump in einen Teil geschrieben

00:46:26.015 --> 00:46:28.235
und dann hat man halt eine in einem String

00:46:28.235 --> 00:46:30.175
serialisierte Form von zum Beispiel irgendwie

00:46:30.175 --> 00:46:32.095
Code. Also mittlerweile nutzt man glaube ich sogar

00:46:32.095 --> 00:46:33.155
Dill oder sowas, ne?

00:46:34.495 --> 00:46:35.775
Dill as Pickle oder so,

00:46:35.915 --> 00:46:38.075
als neue Version. Ja. Als Third-Party-Package

00:46:38.075 --> 00:46:39.815
irgendwie, ja. Schön, schön.

00:46:39.835 --> 00:46:42.115
Können wir auch machen. Okay, aber ein Marschall-Objekt,

00:46:42.175 --> 00:46:44.435
falls ihr das irgendwo findet, ist quasi eine serialisierte

00:46:44.435 --> 00:46:45.875
Form von

00:46:45.875 --> 00:46:48.135
dem, wie es heißt, Code, der da

00:46:48.135 --> 00:46:49.455
gelaufen ist, ja. Genau.

00:46:50.075 --> 00:46:52.195
Okay, jetzt haben wir aber, okay, jetzt haben wir es irgendwo geladen,

00:46:52.255 --> 00:46:53.795
haben wir es gefunden. Was importiert ihr dann?

00:46:53.835 --> 00:46:55.935
Was ruft ihr dann auf? Ja, das

00:46:55.935 --> 00:46:57.835
Ergebnis dieser Ausführung.

00:46:57.935 --> 00:46:59.955
Also import.dot, dann dann import.

00:47:00.355 --> 00:47:00.715
Dann dann.

00:47:02.155 --> 00:47:03.975
In diese Funktion kommen

00:47:03.975 --> 00:47:05.135
dann halt die Argumente rein, die

00:47:05.135 --> 00:47:07.155
Ja, das kann ja alles möglich sein.

00:47:07.155 --> 00:47:09.235
Da kannst du auch beliebige Objekte

00:47:09.235 --> 00:47:10.275
in der Datei reinschreiben.

00:47:10.815 --> 00:47:13.035
Kannst auch ein Modul machen, was einfach nur einen String enthält,

00:47:13.175 --> 00:47:14.435
wo irgendwelche Binärdaten drin sind.

00:47:16.075 --> 00:47:16.975
Macht man ja manchmal,

00:47:17.135 --> 00:47:18.155
weil man Testdaten braucht.

00:47:19.895 --> 00:47:21.075
Das Modul hast, wo einfach

00:47:21.075 --> 00:47:23.035
so ein paar Strings drin sind. Und wenn die

00:47:23.035 --> 00:47:25.055
eben ausgeführt werden, dann werden die halt so einer

00:47:25.055 --> 00:47:26.995
String-Objekt in Python

00:47:26.995 --> 00:47:29.375
mit einem Namen und genau diese

00:47:29.375 --> 00:47:31.295
Sachen, also im Endeffekt ist das halt so

00:47:31.295 --> 00:47:33.315
ein Dictionary, was da drin ist, so ein Unterstrich, Unterstrich,

00:47:33.375 --> 00:47:34.555
Dikt, Unterstrich, Unterstrich.

00:47:34.795 --> 00:47:36.895
Das hat natürlich noch mehr so Attribute, ja.

00:47:37.575 --> 00:47:39.035
Der Path ist da drin

00:47:39.035 --> 00:47:41.115
und der ursprüngliche

00:47:41.115 --> 00:47:43.135
Importname und der Docstring

00:47:43.135 --> 00:47:45.195
wird rausgelesen und so weiter. Also diese ganzen

00:47:45.195 --> 00:47:47.135
Sachen, die halt so passieren, wenn Python was

00:47:47.135 --> 00:47:47.635
ausführt,

00:47:49.095 --> 00:47:51.175
die passieren da auch. Alles das, was Python langsam

00:47:51.175 --> 00:47:53.075
macht. Alles das, was Python awesome

00:47:53.075 --> 00:47:53.435
macht.

00:47:55.055 --> 00:47:59.155
Genau, und das Ergebnis dieser Ausführung ist halt dann das, was das Modul ist.

00:47:59.395 --> 00:48:02.555
Das zusammengefasste Modul. Da gibt es Modul.doc und Modul.tikt und Modul.

00:48:03.335 --> 00:48:07.235
was weiß ich noch alles, .name und .path und .package

00:48:07.235 --> 00:48:11.395
Genau, also alle diese Sachen, die halt dazu gehören. Aber das ist dann schon ein Python-Objekt.

00:48:11.595 --> 00:48:15.635
Also es ist keine Datei mehr, sondern es ist dann ein fertiges Python-Objekt.

00:48:16.355 --> 00:48:19.295
Und auch diese Klassen, die müssen ja erzeugt werden

00:48:19.295 --> 00:48:22.735
und wenn es so Meta-Klassen hat, dann müssen die ausgeführt werden. Also alles das, was da

00:48:22.735 --> 00:48:26.635
wenn man die Datei in den Interpreter eingibt

00:48:26.635 --> 00:48:29.035
und dann alles was da rauskommt

00:48:29.035 --> 00:48:30.135
eben zusammenfasst

00:48:30.135 --> 00:48:33.055
in eine Sache gepackt

00:48:33.055 --> 00:48:35.515
also es ist eigentlich von der Organisationsebene her

00:48:35.515 --> 00:48:36.535
finde ich sehr sauber

00:48:36.535 --> 00:48:38.795
weil alles was in der Datei drin ist

00:48:38.795 --> 00:48:40.995
ist dann eben als Python Objekt verfügbar

00:48:40.995 --> 00:48:44.695
und das ist auch für mich so ein bisschen

00:48:44.695 --> 00:48:47.195
der Grund warum man das braucht

00:48:47.195 --> 00:48:49.615
dass ich halt einfach bestimmte Python Objekte

00:48:49.615 --> 00:48:51.575
oder bestimmte Dinge in andere Dateien

00:48:51.575 --> 00:48:52.355
reinschreiben möchte

00:48:52.355 --> 00:48:54.635
und diese Dateien sollen in anderen Verzeichnissen liegen,

00:48:55.035 --> 00:48:56.275
damit ich nicht die Übersicht verliere.

00:48:57.735 --> 00:48:58.315
Und ja.

00:49:00.515 --> 00:49:01.315
So, das ist Import.

00:49:03.615 --> 00:49:04.215
Und jetzt

00:49:04.215 --> 00:49:05.735
gibt es noch Importlib.

00:49:07.035 --> 00:49:08.595
Ja, das wird ja

00:49:08.595 --> 00:49:10.295
aufgerufen sogar, also Import wird ja Import,

00:49:10.675 --> 00:49:12.115
auch wenn man es nicht überschrieben hat.

00:49:12.215 --> 00:49:14.515
Import ist eigentlich syntaktisch, genau, das kommt ja

00:49:14.515 --> 00:49:16.375
auch noch dazu, das ist ja in dem Artikel

00:49:16.375 --> 00:49:18.615
glaube ich nicht drin, aber in der Diskussion war es dann drin,

00:49:18.615 --> 00:49:20.435
man kann das auch überschreiben, man kann auch

00:49:20.435 --> 00:49:22.155
selber eingreifen in den Importprozess.

00:49:22.355 --> 00:49:24.155
also Dinge, die man

00:49:24.155 --> 00:49:26.695
auf der Liste der Dinge, die man unbedingt tun sollte

00:49:26.695 --> 00:49:27.995
ist das ganz, ganz

00:49:27.995 --> 00:49:29.675
weit unten

00:49:29.675 --> 00:49:34.415
Es gibt

00:49:34.415 --> 00:49:36.635
Importlib und in Python 3 irgendwas

00:49:36.635 --> 00:49:37.855
hat auch

00:49:37.855 --> 00:49:40.695
dieser Importprozess ist quasi

00:49:40.695 --> 00:49:42.515
zu einer Python-Funktionalität geworden

00:49:42.515 --> 00:49:44.735
den man programmatisch

00:49:44.735 --> 00:49:46.415
aufrufen kann, was sehr nützlich ist

00:49:46.415 --> 00:49:48.935
und

00:49:48.935 --> 00:49:50.355
diese Statement

00:49:50.355 --> 00:49:52.675
Import M ist quasi nur noch

00:49:52.675 --> 00:49:54.495
ein syntaktischer Zucker für

00:49:54.495 --> 00:49:56.135
importlib.

00:49:57.035 --> 00:49:58.635
.import

00:49:58.635 --> 00:49:59.735
Ja, irgendwie sowas.

00:50:01.755 --> 00:50:02.235
Das

00:50:02.235 --> 00:50:04.555
coole daran ist, dass man

00:50:04.555 --> 00:50:06.575
eben jetzt in diesen Prozess eingreifen kann.

00:50:06.795 --> 00:50:08.595
Und das ist insbesondere dann für zwei Sachen nützlich.

00:50:08.675 --> 00:50:10.755
Die erste Sache, für die es super nützlich ist,

00:50:12.535 --> 00:50:14.675
da muss ich jetzt leider auf meine eigenen

00:50:15.275 --> 00:50:16.655
Dinge verweisen, da werde ich

00:50:16.655 --> 00:50:18.795
in Kürze ein Video dazu hochladen.

00:50:18.795 --> 00:50:20.275
kommt dann natürlich in die Show.

00:50:20.815 --> 00:50:22.835
Wenn man etwas

00:50:22.835 --> 00:50:23.635
neu laden möchte,

00:50:25.015 --> 00:50:26.295
weil

00:50:26.295 --> 00:50:28.515
wir haben ja eben besprochen, wenn ich Import M

00:50:28.515 --> 00:50:30.615
mache, dann wird es einmal geladen

00:50:30.615 --> 00:50:31.135
und dann nie wieder.

00:50:32.095 --> 00:50:34.275
Man ist ja jetzt oft als Softwareentwickler in so einer Situation,

00:50:34.435 --> 00:50:36.295
dass man Dateien dann verändert und die

00:50:36.295 --> 00:50:37.875
eigentlich sofort

00:50:37.875 --> 00:50:40.435
haben möchte, ohne dass man das Programm

00:50:40.435 --> 00:50:42.555
neu startet. Und um das hinzukriegen,

00:50:43.295 --> 00:50:44.495
habe ich mir halt so ein bisschen

00:50:44.495 --> 00:50:46.455
einen Glue-Code geschrieben, der Dateien

00:50:46.455 --> 00:50:48.475
überwacht und wenn die sich ändern, dann wird da halt

00:50:48.475 --> 00:50:49.915
Reimport durchgeführt.

00:50:50.375 --> 00:50:52.295
Und das ist möglich durch die Funktion

00:50:52.295 --> 00:50:54.275
aus Importlib. Da kann ich sagen,

00:50:54.375 --> 00:50:56.295
importiere diese spezifische Datei,

00:50:58.095 --> 00:50:58.515
auch wenn

00:50:58.515 --> 00:50:59.495
die schon mal importiert war,

00:51:00.635 --> 00:51:01.175
und dann

00:51:01.175 --> 00:51:04.295
wird die importiert. Egal, ob die schon im

00:51:04.295 --> 00:51:06.295
Cache liegt oder nicht. Ja, cool. Ja, ich meine,

00:51:06.675 --> 00:51:08.075
der Entwicklungshelfer von Junkmo,

00:51:08.115 --> 00:51:10.175
der kann sowas ja auch. Ja, aber der macht ja

00:51:10.175 --> 00:51:11.855
einen Neustart. Der macht tatsächlich einen Neustart, naja.

00:51:12.435 --> 00:51:14.315
Der hat so einen Watcher-Prozess und dann

00:51:14.315 --> 00:51:16.035
schießt er einfach den Prozess ab und startet einmal neu.

00:51:16.095 --> 00:51:17.855
Ach so, ich weiß gar nicht, wie das

00:51:17.855 --> 00:51:20.375
gut, das ist ja, oh mein Gott, das ist ja schrecklich.

00:51:21.195 --> 00:51:22.395
Ja, aber es hat auch Vorteile,

00:51:22.515 --> 00:51:24.195
weil dann halt alles

00:51:24.195 --> 00:51:24.995
auf Null zurück ist.

00:51:27.335 --> 00:51:28.055
Wie ist das denn bei

00:51:28.055 --> 00:51:29.775
Jupyter, ist das ja auch so, da kann ich ja auch beim

00:51:29.775 --> 00:51:32.095
Import sagen, ob ich das jetzt möchte,

00:51:32.215 --> 00:51:34.215
dass ich das nochmal importieren will,

00:51:34.275 --> 00:51:35.755
wenn es sich ändert. Ja, dann mach doch ein Reimport.

00:51:36.435 --> 00:51:38.375
Da gibt es eben diese Jupyter Magic,

00:51:38.735 --> 00:51:40.275
die du sagen kannst, und der benutzt

00:51:40.275 --> 00:51:41.675
tatsächlich Import-Lib und macht Reimport.

00:51:42.295 --> 00:51:43.155
Aha, okay.

00:51:45.555 --> 00:51:46.655
Neustarten wäre auch blöd.

00:51:46.655 --> 00:51:48.015
an der Stelle.

00:51:48.235 --> 00:51:50.035
Geht ja auch an der Stelle einfach gar nicht.

00:51:51.335 --> 00:51:52.975
Zum einen, weil der Prozess ja da

00:51:52.975 --> 00:51:54.975
läuft und zum anderen, weil

00:51:54.975 --> 00:51:56.675
der die anderen Zellen nicht kaputt machen will.

00:51:56.795 --> 00:51:57.735
Das heißt ja, die Zellen immer noch.

00:51:58.835 --> 00:52:00.355
Ich hatte übrigens tatsächlich jetzt

00:52:00.355 --> 00:52:01.835
letzte,

00:52:02.255 --> 00:52:04.755
vorletzte, nee, letzte oder vorletzte, nee, glaube letzte

00:52:04.755 --> 00:52:06.335
Woche, und ich erinnere mich schon nicht mehr dran,

00:52:06.655 --> 00:52:08.835
den Fall, wo ich tatsächlich Importlib gebraucht

00:52:08.835 --> 00:52:10.775
habe und habe halt die Importfunktion

00:52:10.775 --> 00:52:11.295
überschrieben.

00:52:12.755 --> 00:52:13.875
Was hast du damit gemacht?

00:52:13.875 --> 00:52:15.775
für einen, ich habe einen

00:52:15.775 --> 00:52:17.535
Pull-Request bei Wagtail Media

00:52:17.535 --> 00:52:19.935
eingereicht, weil

00:52:19.935 --> 00:52:21.935
es nicht mit Wagtail 2.13 kompatibel war.

00:52:24.295 --> 00:52:27.615
Und da gibt es Tests

00:52:27.615 --> 00:52:29.415
und das Problem ist jetzt,

00:52:30.115 --> 00:52:31.815
man möchte die Tests

00:52:31.815 --> 00:52:33.795
ja, also da ist

00:52:33.795 --> 00:52:35.835
dann, okay, ich fange einfach mal von der Seite

00:52:35.835 --> 00:52:37.375
an, es gibt im Code so Dinge wie

00:52:37.375 --> 00:52:39.375
probier das mal zu importieren,

00:52:39.615 --> 00:52:41.875
wenn es schief geht, mach was anderes, weil

00:52:41.875 --> 00:52:43.595
zum Beispiel diese Telepath

00:52:43.595 --> 00:52:45.295
Bibliothek gibt es erst ab Worktel

00:52:45.295 --> 00:52:45.795
2013.

00:52:47.635 --> 00:52:49.075
Und da sagt man halt, probiere es zu importieren.

00:52:49.075 --> 00:52:51.315
Ja, auch für lokale, ich benutze es ganz häufig für lokale

00:52:51.315 --> 00:52:53.775
Settings, ja. Irgendwo eine local settings.py

00:52:53.775 --> 00:52:54.635
und dann macht man halt

00:52:54.635 --> 00:52:57.675
try import local settings.py

00:52:57.675 --> 00:52:58.815
und accept pass.

00:52:59.215 --> 00:53:01.575
Ja. Genau, genau.

00:53:02.015 --> 00:53:03.255
Und jetzt müsste man das aber testen.

00:53:03.335 --> 00:53:04.695
Jetzt möchte man testen, dass wenn

00:53:04.695 --> 00:53:07.555
und es gibt da noch kompliziertere,

00:53:07.555 --> 00:53:09.735
wie gesagt, das habe ich jetzt wieder vergessen, blöderweise, ein bisschen kompliziertere

00:53:09.735 --> 00:53:11.595
Logik, die davon abhängt, ob man es jetzt geschafft

00:53:11.595 --> 00:53:12.695
hat, das zu importieren oder nicht.

00:53:12.695 --> 00:53:19.775
und jetzt, wie willst du das testen, ob jetzt wirklich der richtige Code ausgeführt wird, also der Code, der zum Beispiel dann nur so ein Dummy-Objekt anlegt,

00:53:20.695 --> 00:53:28.015
wie willst du testen, ob das funktioniert hat, wenn du nicht dann noch eine andere Paketversion installieren willst, was du im Test auch nicht gut machen kannst?

00:53:28.515 --> 00:53:35.475
Ja, und dann habe ich da einfach quasi Import-Funktionen überschrieben und dann in der Import-Funktion gucke ich halt so, wird gerade versucht, das da zu importieren?

00:53:35.655 --> 00:53:39.555
Ja, wirklich? Gut. Race-Exception, ja, und dann Race-Import-Error.

00:53:39.555 --> 00:53:43.475
und dann kann man halt testen, okay, und ist jetzt wirklich das Sammely-Objekt, ja oder nein?

00:53:43.835 --> 00:53:44.775
Und dann hat man einen Test dafür.

00:53:45.715 --> 00:53:47.335
Ja, aber fand ich spannend.

00:53:47.595 --> 00:53:49.595
Das ist auch ganz schön tief eingegriffen.

00:53:49.915 --> 00:53:51.755
Ach, der Jochen auch aufgenommen?

00:53:52.475 --> 00:53:53.615
Ja, genau.

00:53:54.255 --> 00:53:55.455
Du musst jetzt aber suchen, in welcher Folge das war.

00:53:55.455 --> 00:53:56.475
Kannst du uns da einen Link geben, Jochen?

00:53:56.535 --> 00:53:57.875
Kann ich auch mal in die Schauenden folgen.

00:53:58.175 --> 00:53:58.675
Das ist ja cool.

00:53:59.615 --> 00:53:59.795
Ja.

00:54:01.535 --> 00:54:03.015
Ja, was kann denn noch alles dann passieren?

00:54:03.295 --> 00:54:08.395
Genau, das ist jetzt sozusagen, der Jochen hat jetzt hier schon die Brücke zu dem zweiten Anwendungsfall geschlagen,

00:54:08.395 --> 00:54:10.575
was dann eben hier aus diesem Artikel in der Diskussion

00:54:10.575 --> 00:54:12.335
rauskam, man kann auch

00:54:12.335 --> 00:54:14.275
im Importsystem was anderes

00:54:14.275 --> 00:54:15.295
machen

00:54:15.295 --> 00:54:18.535
und der schöne Vorschlag, der da kam

00:54:18.535 --> 00:54:20.335
beziehungsweise das schöne Beispiel, was da in

00:54:20.335 --> 00:54:22.155
dieser Diskussion kam, ist

00:54:22.155 --> 00:54:24.295
dass man ja prinzipiell auch andere Sprachen

00:54:24.295 --> 00:54:26.315
integrieren könnte. Einfach Importsystem auf einen ansetzen

00:54:26.315 --> 00:54:28.335
Das kann man auch machen, dann ist man in

00:54:28.335 --> 00:54:29.195
seiner eigenen Welt

00:54:29.195 --> 00:54:32.395
aber quasi das Gegenteil

00:54:32.395 --> 00:54:34.375
davon ist, wenn kein Python-Modul

00:54:34.375 --> 00:54:36.275
gefunden wird, dann kann man ja mal schauen, ob man irgendwas anderes

00:54:36.275 --> 00:54:37.755
kompilieren kann, was diesen Namen hat

00:54:37.755 --> 00:54:40.255
und wenn das

00:54:40.255 --> 00:54:42.075
kompilierbar ist und kompiliert, dann einfach das

00:54:42.075 --> 00:54:44.235
importieren. Und es hat wohl jemand

00:54:44.235 --> 00:54:46.535
geschrieben, dass jemand sich eben so Lisp-Dateien

00:54:46.535 --> 00:54:48.015
rein importieren kann, die

00:54:48.015 --> 00:54:50.255
live kompiliert werden, wenn man

00:54:50.255 --> 00:54:50.835
sie importiert.

00:54:53.035 --> 00:54:54.355
Reichlich abgefahren, würde ich sagen

00:54:54.355 --> 00:54:56.135
und ich empfehle auch niemandem, diesen

00:54:56.135 --> 00:54:58.255
Weg zu gehen, aber es ist

00:54:58.255 --> 00:54:59.915
schön, dass es jemanden gibt, der das

00:54:59.915 --> 00:55:01.615
gemacht hat und das möglich ist.

00:55:03.595 --> 00:55:04.235
Ich wüsste

00:55:04.235 --> 00:55:06.175
jetzt tatsächlich keinen richtig sinnvollen

00:55:06.175 --> 00:55:07.375
Anwendungszweck davon, aber

00:55:07.375 --> 00:55:08.895
Ja.

00:55:11.575 --> 00:55:12.195
Irgendwann wird es

00:55:12.195 --> 00:55:13.355
einen Anwendungsfall geben.

00:55:13.455 --> 00:55:14.615
Ich habe gerade überlegt,

00:55:14.715 --> 00:55:18.875
wenn man das jetzt mit TypeScript macht,

00:55:19.335 --> 00:55:21.195
man möchte auf dem Backend

00:55:21.195 --> 00:55:22.255
und vorne den gleichen Code.

00:55:23.075 --> 00:55:24.275
Ja, und dann wird es noch

00:55:24.275 --> 00:55:27.035
mit dem JavaScript to Python

00:55:27.035 --> 00:55:28.455
Compiler noch Python gemacht.

00:55:29.035 --> 00:55:29.995
Dann hat man noch einen Server,

00:55:30.095 --> 00:55:31.395
was WebAssembly kann.

00:55:32.715 --> 00:55:34.435
Man kann Python schreiben für Frontend.

00:55:34.435 --> 00:55:35.335
Und schon

00:55:35.335 --> 00:55:46.775
eigenes, die eigene, deine Dateien bestehen quasi nur noch aus Import Statements. Alles mit Import Statements gemacht. Ja, das ist so wie der Präprozessor, der ist auch Turing vollständig.

00:55:47.455 --> 00:55:48.355
Ja, tja.

00:55:50.575 --> 00:55:52.815
Da hat jemand super wieder sein...

00:55:52.815 --> 00:55:57.275
Vorhin haben wir noch drüber gesprochen, ob wir unser Telefon ausschalten wollen.

00:55:57.275 --> 00:55:59.195
Flugmodus gestellt, aber nicht

00:55:59.195 --> 00:55:59.575
mein Rechner.

00:56:00.995 --> 00:56:02.635
Auf meinem Telefon hat es auch nicht geklingelt, sondern

00:56:02.635 --> 00:56:05.475
mein Rechner kann halt auch dummerweise klingeln.

00:56:05.875 --> 00:56:07.315
Was kann denn noch alles schief gehen bei den

00:56:07.315 --> 00:56:09.295
Importen? Ja, eigentlich kann beim Importen alles

00:56:09.295 --> 00:56:10.575
schief gehen, oder? Das ist ja...

00:56:10.575 --> 00:56:13.075
Ja. Da steht irgendwas

00:56:13.075 --> 00:56:15.035
komisches drin, also keine Binärcodes oder irgendein andere

00:56:15.035 --> 00:56:16.415
Zeichen, das er nicht lesen kann oder sowas.

00:56:17.375 --> 00:56:19.335
Ja, es kann auch...

00:56:19.335 --> 00:56:21.315
Ich glaube, das Schwierigste an diesem Importsystem

00:56:21.315 --> 00:56:22.755
ist, dass es halt manchmal überraschend ist.

00:56:22.875 --> 00:56:25.215
Dass es einem Sachen versucht zu importieren,

00:56:25.495 --> 00:56:26.635
die man nicht gemeint hat.

00:56:27.275 --> 00:56:30.015
weil die Reihenfolge im Path falsch ist

00:56:30.015 --> 00:56:32.015
oder weil da Module liegen, die man noch nicht kennt

00:56:32.015 --> 00:56:33.795
oder weil man versehentlich

00:56:33.795 --> 00:56:35.635
einen Namen verwendet hat, den es schon gibt.

00:56:36.655 --> 00:56:37.855
Also wenn man so eine Kette durchgeht,

00:56:38.035 --> 00:56:39.855
also man möchte jetzt A importieren und A

00:56:39.855 --> 00:56:41.855
möchte aber jetzt C, D, E, F, G und

00:56:41.855 --> 00:56:43.955
Genau, sowas kann natürlich auch passieren, dann hast du zirkuläre

00:56:43.955 --> 00:56:45.895
Imports, das ist auch schlecht.

00:56:46.575 --> 00:56:48.395
Ja, aber das wäre ja von A von B und B von C

00:56:48.395 --> 00:56:49.735
und C von A. Ja genau,

00:56:49.955 --> 00:56:50.875
und das hat man ja manchmal.

00:56:51.575 --> 00:56:53.375
Aber das war ein anderes Problem, als das ich gerade meinte.

00:56:53.915 --> 00:56:55.415
Das ist also ganz, ganz, ganz viel Zeug.

00:56:55.415 --> 00:56:57.495
importiert. Also du könntest ja quasi eine Sache importieren, der importiert

00:56:57.495 --> 00:56:58.635
alles andere, die ganze Standard-Python.

00:56:58.975 --> 00:57:01.015
Im Prinzip machst du das ja so in deinem Skript.

00:57:01.875 --> 00:57:03.475
Das ist halt so relativ getarnt,

00:57:03.815 --> 00:57:05.315
was da passiert. Man macht relativ viel

00:57:05.315 --> 00:57:06.055
Magie schon.

00:57:09.355 --> 00:57:11.255
Die komplizierte

00:57:11.255 --> 00:57:13.335
Frage wäre, ob das das dann doch langsam macht,

00:57:13.695 --> 00:57:15.115
wenn man sowas raussucht und sagt,

00:57:15.215 --> 00:57:17.295
beim ersten Mal schon. Das heißt, da kann der Starten

00:57:17.295 --> 00:57:19.235
relativ lange dauern und beim zweiten Mal

00:57:19.235 --> 00:57:21.155
vielleicht nicht. Aber es gab irgendwie

00:57:21.155 --> 00:57:23.175
so ein Problem, dass irgendwer hatte, der das

00:57:23.175 --> 00:57:24.895
mal ausprobiert hat wegen den Imports.

00:57:25.415 --> 00:57:27.735
immer wieder. Ja, ja, ja. Also das Problem

00:57:27.735 --> 00:57:29.495
gibt es halt, wenn du halt irgendwie so auf die Richtung

00:57:29.495 --> 00:57:31.435
weiß ich nicht, Millionenzeilen

00:57:31.435 --> 00:57:33.515
Python oder so zugehst, dass eben dann, wenn das

00:57:33.515 --> 00:57:35.575
zum Beispiel im Entwicklungsserver, wenn der neu startet,

00:57:35.595 --> 00:57:37.235
wenn du änderst irgendwas, dann startet der neu

00:57:37.235 --> 00:57:38.915
und dann dauert das halt eine Minute.

00:57:39.455 --> 00:57:41.275
Das ist halt schlecht. Das ist halt immer so richtig

00:57:41.275 --> 00:57:43.595
flüssig beim Entwickeln. Es hieß ja

00:57:43.595 --> 00:57:45.375
irgendwie so, ne, wir haben das Google, aber ich glaube,

00:57:45.415 --> 00:57:46.755
das war bei Instagram das Problem oder so.

00:57:47.235 --> 00:57:49.035
Ja, bei Instagram gibt es auch bei

00:57:49.035 --> 00:57:51.615
Eventbrite gibt es das, glaube ich, auch.

00:57:51.795 --> 00:57:53.295
Ja, die sind nicht so groß wie Google.

00:57:53.815 --> 00:57:54.815
Ja, aber die haben, glaube ich, auch irgendwie

00:57:54.815 --> 00:57:55.535
oder

00:57:55.535 --> 00:57:58.455
verwechsel ich das gerade?

00:57:58.575 --> 00:58:00.375
Ich meine, es ist Eventbrite, aber auch ungefähr eine Million

00:58:00.375 --> 00:58:02.195
Zahlencode und Instagram halt auch

00:58:02.195 --> 00:58:03.695
vielleicht noch mehr, weiß ich.

00:58:04.335 --> 00:58:06.195
Ja, okay. Aber das ist ja dann so

00:58:06.195 --> 00:58:07.795
ein...

00:58:07.795 --> 00:58:10.375
Das Problem ist ja eigentlich, dass halt die Sachen

00:58:10.375 --> 00:58:12.455
erst so in Anführungszeichen kompiliert werden,

00:58:12.575 --> 00:58:13.575
wenn ich Import sage.

00:58:14.295 --> 00:58:16.195
Und deshalb haben andere Sprachen das nicht, weil die

00:58:16.195 --> 00:58:17.475
machen das halt einmal vorher.

00:58:18.975 --> 00:58:20.235
Aber so eine richtig gute Lösung,

00:58:20.235 --> 00:58:22.055
also ich meine, es gibt PyO-Dateien

00:58:22.055 --> 00:58:23.115
und PyC-Dateien,

00:58:23.115 --> 00:58:25.235
die sind ja wohl schneller

00:58:25.235 --> 00:58:26.455
ja

00:58:26.455 --> 00:58:28.655
oder könnte man

00:58:28.655 --> 00:58:30.415
sowas auch marscheln

00:58:30.415 --> 00:58:33.215
könnte man Imports durchführen

00:58:33.215 --> 00:58:34.995
und das dann, ja im Prinzip schon oder

00:58:34.995 --> 00:58:36.315
wahrscheinlich schon ja

00:58:36.315 --> 00:58:37.575
einfach mal alles gepickelt

00:58:37.575 --> 00:58:38.875
ja

00:58:38.875 --> 00:58:43.055
ach deswegen auch weil der Pickel ist die Haube von dem Marschall

00:58:43.055 --> 00:58:43.975
jetzt verstehe ich das auch

00:58:43.975 --> 00:58:46.775
ich dachte Pickel ist so ein Einmachglas

00:58:46.775 --> 00:58:48.975
Marschalls haben doch so eine Pickelhaube auf

00:58:48.975 --> 00:58:51.175
ja, also dann passt das auf jeden Fall

00:58:51.175 --> 00:58:51.535
zusammen

00:58:51.535 --> 00:58:53.775
Das ist doch zumindest schon irgendwie

00:58:53.775 --> 00:58:54.715
Sorry, weigert es

00:58:54.715 --> 00:58:57.055
Das Englische, wo Pickels heißt, eingemacht ist

00:58:57.055 --> 00:58:58.075
Ja, ja

00:58:58.075 --> 00:59:00.115
Ich glaube, das ist die

00:59:00.115 --> 00:59:02.835
Okay, aber zirkuläre Importe wollte ich nochmal

00:59:02.835 --> 00:59:04.915
Ja, zirkuläre Importe sind auch eine schöne Sache

00:59:04.915 --> 00:59:06.655
Also man kann ja sowas machen wie in Python

00:59:06.655 --> 00:59:07.695
Form A, Import B und dann

00:59:07.695 --> 00:59:10.215
B machen, Form B, Import irgendwas

00:59:10.215 --> 00:59:11.995
oder Import A, Import B, Import D und so

00:59:11.995 --> 00:59:14.895
und das funktioniert einfach, aber erst wenn man es dann ausführt

00:59:14.895 --> 00:59:17.235
dann nicht mehr, weil er dann darauf zugreift

00:59:17.235 --> 00:59:18.615
und dann sagt, das kennt er noch nicht

00:59:18.615 --> 00:59:21.095
Genau, beziehungsweise ist schon geladen

00:59:21.095 --> 00:59:22.515
oder ist schon am Laden.

00:59:23.175 --> 00:59:24.255
Also wenn ich

00:59:24.255 --> 00:59:26.955
zirkuläre Verweise

00:59:26.955 --> 00:59:28.875
habe, vom A Import B und in B

00:59:28.875 --> 00:59:30.775
sage ich vom, wenn ich

00:59:30.775 --> 00:59:32.895
Modul A und B habe und in A

00:59:32.895 --> 00:59:34.795
sage ich Import B und in B sage ich Import A,

00:59:35.215 --> 00:59:36.975
dann kann ich die beide nicht importieren, weil zu dem

00:59:36.975 --> 00:59:38.435
Zeitpunkt müsste ich sie beide gleichzeitig

00:59:38.435 --> 00:59:40.655
importieren und das geht nicht.

00:59:41.915 --> 00:59:43.175
Und da kann ich natürlich beliebig

00:59:43.175 --> 00:59:45.015
viele dazwischen schieben. Ich kann A, B,

00:59:45.195 --> 00:59:47.015
C, D, E, S. Solange dieser

00:59:47.015 --> 00:59:49.455
Kreis sich irgendwann schließt,

00:59:49.455 --> 00:59:49.955
ist schlecht.

00:59:51.095 --> 00:59:52.975
Also es fällt ja direkt auf. Ich glaube, wenn man drei hat,

00:59:53.075 --> 00:59:54.375
dann fällt es glaube ich nicht immer direkt auf.

00:59:54.775 --> 00:59:56.815
Wenn man vier oder fünf hat, dann fällt es erst recht.

00:59:58.115 --> 00:59:59.095
Das siehst du dann beim

00:59:59.095 --> 01:00:00.755
Importieren. Und wie löst man das denn, wenn man

01:00:00.755 --> 01:00:01.475
so ein Problem hat?

01:00:03.635 --> 01:00:04.415
Laufzeit-Imports.

01:00:04.675 --> 01:00:05.735
Also lazy quasi.

01:00:06.275 --> 01:00:08.635
Das ist doch das, was man in so

01:00:08.635 --> 01:00:10.195
Salary-Tasks immer machen muss.

01:00:10.875 --> 01:00:12.935
Weil diese Tasks können von irgendwo her

01:00:12.935 --> 01:00:14.815
gestartet werden und die sollen dann irgendwas machen.

01:00:15.875 --> 01:00:16.955
Und die müssen

01:00:16.955 --> 01:00:18.875
ja auch irgendwie diese Modelle importieren, aber das Modell

01:00:18.875 --> 01:00:29.623
selber m Also das ist so mein klassischer anwendungsweise Ich m dem Modell sagen ich muss hier Werte nachberechnen ich muss hier ein PDF erzeugen und das dauert lange und deshalb mache ich

01:00:29.623 --> 01:00:31.522
das in dem Task. Aber dieser Task soll ja dann wieder

01:00:31.522 --> 01:00:33.042
dieses ursprüngliche Modell speichern.

01:00:33.683 --> 01:00:35.842
Das heißt, ich kann in der Tasks-Datei

01:00:35.842 --> 01:00:37.022
nicht das Modell importieren,

01:00:37.482 --> 01:00:39.383
weil das Modell hat schon den Task importiert.

01:00:40.183 --> 01:00:41.542
Und deshalb ist das so ein

01:00:41.542 --> 01:00:43.403
Pattern, wenn man Celery-Tasks schreibt,

01:00:43.962 --> 01:00:44.982
dass diese Tasks

01:00:44.982 --> 01:00:47.383
zur Laufzeit alles importieren. Also

01:00:47.383 --> 01:00:49.542
in der Datei, in der Funktion

01:00:49.542 --> 01:00:51.683
dev compute pdf.

01:00:52.842 --> 01:00:53.782
Da habe ich erst mal ein paar

01:00:53.782 --> 01:00:55.663
Importzeilen drin. Import from models

01:00:55.663 --> 01:00:56.462
import irgendwas.

01:00:57.383 --> 01:00:58.502
Import pdf generator.

01:00:59.542 --> 01:01:01.643
Und noch alles, was man da halt so importiert

01:01:01.643 --> 01:01:03.542
braucht. Und dann werden diese

01:01:03.542 --> 01:01:05.362
Imports erst ausgeführt, wenn die

01:01:05.362 --> 01:01:07.482
Funktion gestartet wird. Also von mir, von meinem

01:01:07.482 --> 01:01:09.062
geistigen Auge, die ich mir gerade so ein paar Tickets ziehe.

01:01:09.183 --> 01:01:10.262
Die To-Do-Listen müssen ja an.

01:01:11.923 --> 01:01:12.362
Genau.

01:01:13.262 --> 01:01:15.282
Das bedeutet halt, dass dieser Import nicht

01:01:15.282 --> 01:01:17.102
ausgeführt wird, wenn die Datei geladen wird.

01:01:18.702 --> 01:01:19.442
Was eben der

01:01:19.442 --> 01:01:21.163
Fall wäre, wenn es oben in der Datei drinstehende,

01:01:21.542 --> 01:01:23.542
sondern dieser Import wird erst ausgeführt,

01:01:23.643 --> 01:01:25.542
wenn die Funktion, die da drin ist, gestartet wird.

01:01:25.643 --> 01:01:27.183
Weil quasi nur der

01:01:27.183 --> 01:01:29.202
Funktionsname geladen wird und das, was

01:01:29.202 --> 01:01:30.822
passieren soll quasi. Genau, richtig.

01:01:31.502 --> 01:01:33.282
Und wenn ich diese Funktion dann ausführe,

01:01:33.442 --> 01:01:35.282
dann wird dieses Import Statement ausgeführt.

01:01:36.062 --> 01:01:37.342
Und dann sind die anderen Sachen schon da

01:01:37.342 --> 01:01:39.202
und dann hat man quasi den Laser Import, dann kann man

01:01:39.202 --> 01:01:40.822
das dann wieder machen, weil die sind ja schon...

01:01:40.822 --> 01:01:43.183
Das ist dann schon fertig, importiere diese Models, die sind schon im Cache,

01:01:43.262 --> 01:01:45.102
dann kann ich einfach in den Cache zeigen und sagen, hier gibt man das.

01:01:46.702 --> 01:01:47.163
Bin also

01:01:47.163 --> 01:01:48.702
sozusagen aus diesem Prozess raus.

01:01:48.702 --> 01:01:51.123
und das ist auch sowas, was eben

01:01:51.123 --> 01:01:52.442
anders ist als in anderen Sprachen.

01:01:52.582 --> 01:01:55.002
Import ist ein Statement, was einen Effekt hat.

01:01:56.222 --> 01:01:57.002
In C, wenn ich

01:01:57.002 --> 01:01:58.883
in C sage, import header.h,

01:01:59.362 --> 01:02:00.542
dann hat es keinen Effekt,

01:02:00.962 --> 01:02:02.582
das ist kein Code, der da erzeugt wird.

01:02:03.683 --> 01:02:04.722
Punkt H ist immer Header,

01:02:04.923 --> 01:02:05.842
noch mal für alle Leute kein C.

01:02:06.362 --> 01:02:08.362
Punkt H ist immer Header, das sind so die

01:02:08.362 --> 01:02:10.962
Definitionen, die Deklarationen,

01:02:10.982 --> 01:02:13.082
nicht die Definitionen, die Deklarationen, was es da gibt

01:02:13.082 --> 01:02:14.962
und die Punkt C Datei enthält

01:02:14.962 --> 01:02:17.242
dann die Definitionen normalerweise.

01:02:17.242 --> 01:02:20.482
Also Header.h ist natürlich die Definition der Header.

01:02:20.982 --> 01:02:21.702
Die Definition,

01:02:21.702 --> 01:02:23.242
da muss ich dann eine

01:02:23.242 --> 01:02:25.462
Datei dazugeben, die heißt

01:02:25.462 --> 01:02:26.082
Header.c

01:02:26.082 --> 01:02:29.002
War nur ein Beispiel.

01:02:30.562 --> 01:02:30.962
Aber

01:02:30.962 --> 01:02:33.683
dieses Import-Statement in einem c,

01:02:33.822 --> 01:02:35.602
das wird vom Compiler ausgeführt, das wird nicht

01:02:35.602 --> 01:02:37.302
zur Laufzeit ausgeführt.

01:02:37.403 --> 01:02:38.342
Und in Python ist das anders.

01:02:38.842 --> 01:02:39.942
Der Compiler, der macht das,

01:02:40.423 --> 01:02:43.702
der schneidet die einfach zusammen, alle zu einer großen Datei

01:02:43.702 --> 01:02:44.822
und dann liest der einfach von oben nach unten.

01:02:44.822 --> 01:02:46.962
und dann gibt es noch den Linker, der dann dafür

01:02:46.962 --> 01:02:48.982
sorgt, dass diese Verweise alle an der korrekten Stelle

01:02:48.982 --> 01:02:50.782
in die korrekte Stelle zeigen. Das ist so ein

01:02:50.782 --> 01:02:53.022
mehrstufiger Prozess und es ist halt alles

01:02:53.022 --> 01:02:54.242
bevor das Programm gestartet wird.

01:02:54.822 --> 01:02:55.842
Und in Python ist immer alles

01:02:55.842 --> 01:02:58.822
nachdem das Programm gestartet wird.

01:02:59.183 --> 01:03:00.782
Und das ist halt hier genau das Problem. Wenn ich

01:03:00.782 --> 01:03:02.383
Import B sage und

01:03:02.383 --> 01:03:05.082
versuche aber schon was zu importieren

01:03:05.082 --> 01:03:07.123
oder versuche schon B zu importieren,

01:03:07.222 --> 01:03:08.623
dann geht es halt nicht.

01:03:09.302 --> 01:03:11.082
Weil das dann eben so einen Kreis

01:03:11.082 --> 01:03:12.502
bildet, der nicht aufgelöst werden kann.

01:03:12.942 --> 01:03:14.442
Wenn ich das aber erst später im Programm sage,

01:03:14.442 --> 01:03:16.383
wenn ich irgendwelche Funktionen geladen habe,

01:03:17.143 --> 01:03:18.482
die dann später nochmal

01:03:18.482 --> 01:03:20.242
diese Module brauchen.

01:03:20.822 --> 01:03:21.782
Ist egal, wo die herkommen.

01:03:22.582 --> 01:03:24.062
Wenn die schon im Cache sind, einwandfrei.

01:03:24.482 --> 01:03:26.183
Okay, aber das widerspricht ja so ein bisschen dieser

01:03:26.183 --> 01:03:27.942
Philosophie, dass Importe immer ganz oben stehen.

01:03:28.042 --> 01:03:30.282
Ja, genau. Deshalb ist das hier so der

01:03:30.282 --> 01:03:31.782
Nachteil da dran.

01:03:32.102 --> 01:03:34.123
Ja, ich fühle mich da auch immer so ein bisschen schmutzig, aber

01:03:34.123 --> 01:03:36.322
ja, ich mache das auch so. Aber es ist halt das Pattern

01:03:36.322 --> 01:03:38.183
und das ist der beste Weg außenrum.

01:03:38.502 --> 01:03:39.982
Es gibt noch eine andere Möglichkeit,

01:03:40.643 --> 01:03:42.322
die ich auch

01:03:42.322 --> 01:03:44.202
niemandem empfehlen möchte. Es ist ein sehr schöner Hack,

01:03:44.202 --> 01:03:45.002
den ich mal gehört habe.

01:03:45.883 --> 01:03:48.423
Wenn ich jetzt zum Beispiel nur einen Task importieren möchte,

01:03:48.522 --> 01:03:49.862
dann sage ich from tasks import

01:03:49.862 --> 01:03:50.482
greatpdf.

01:03:51.643 --> 01:03:53.923
Und der Importprozess führt

01:03:53.923 --> 01:03:56.123
tatsächlich nur so lange diesen Import

01:03:56.123 --> 01:03:58.002
aus, bis dieses Objekt vorhanden ist.

01:04:00.242 --> 01:04:02.362
Alles was unterhalb dieses Objektes ist,

01:04:03.362 --> 01:04:04.183
wird

01:04:04.183 --> 01:04:04.782
nicht ausgeführt.

01:04:05.602 --> 01:04:07.623
Das heißt, wenn ich meine Importstatements

01:04:07.623 --> 01:04:09.462
ans Ende einer Datei mache,

01:04:10.722 --> 01:04:13.663
dann kann ich zirkuläre Importe

01:04:13.663 --> 01:04:14.062
machen,

01:04:14.842 --> 01:04:17.722
in bestimmten Situationen, dann geht

01:04:17.722 --> 01:04:17.962
das.

01:04:19.923 --> 01:04:20.282
Aber

01:04:20.282 --> 01:04:23.623
das, wie gesagt, ist keine

01:04:23.623 --> 01:04:24.602
Empfehlung. Es ist nur

01:04:24.602 --> 01:04:27.562
Imports ans Ende der Datei schreiben ist

01:04:27.562 --> 01:04:29.643
schon generell schlecht, weil man sie dann nicht mehr sieht

01:04:29.643 --> 01:04:31.502
und es ist auch dann schlecht, wenn man dann

01:04:31.502 --> 01:04:33.542
zirkuläre Importe... Das kann man dann wahrscheinlich auch noch

01:04:33.542 --> 01:04:35.462
ein bisschen verschachteln oder so. Also alle Leute, die

01:04:35.462 --> 01:04:37.623
ein größeres Interesse

01:04:37.623 --> 01:04:39.302
an Job Security haben, jetzt mal

01:04:39.302 --> 01:04:40.362
aufpassen mit Schreiben.

01:04:42.143 --> 01:04:43.602
Das kriegt man hinterher nie wieder aus

01:04:43.602 --> 01:04:47.362
und wenn man dann noch

01:04:47.362 --> 01:04:49.582
Homoglyphen nimmt und die Dateien

01:04:49.582 --> 01:04:51.242
alle gleich ausschauen, dann

01:04:51.242 --> 01:04:53.163
hat man ganz gewonnen.

01:04:55.403 --> 01:04:57.362
Ja, das ist ein Hack, der

01:04:57.362 --> 01:04:59.582
die Interna missbraucht, würde ich nicht empfehlen,

01:04:59.722 --> 01:05:00.903
aber es ist schön, dass es das gibt.

01:05:03.222 --> 01:05:03.582
Ja,

01:05:03.782 --> 01:05:05.123
ist auch manchmal interessant

01:05:05.123 --> 01:05:07.502
zu wissen, warum irgendwas funktioniert, wo man

01:05:07.502 --> 01:05:09.222
denkt, das kann gar nicht funktionieren, aber es funktioniert

01:05:09.222 --> 01:05:09.602
dann doch.

01:05:11.782 --> 01:05:12.362
Ja, ja.

01:05:13.602 --> 01:05:17.623
Nicht so selten, wie es funktioniert, was nicht, was eigentlich funktionieren sollte, aber trotzdem auch.

01:05:17.623 --> 01:05:17.883
Leider.

01:05:21.082 --> 01:05:21.442
Ja.

01:05:23.222 --> 01:05:24.582
Ja, Imports haben wir, oder?

01:05:24.922 --> 01:05:25.123
Ja.

01:05:25.362 --> 01:05:27.262
Erklärt, oder fällt euch noch was ein?

01:05:28.022 --> 01:05:30.082
Bin mir sicher, dass da noch ganz viele Fragen kommen.

01:05:30.183 --> 01:05:31.903
Vor allem, wie funktionieren Imports in anderen Sprachen?

01:05:32.982 --> 01:05:33.342
Ja, anders.

01:05:33.342 --> 01:05:35.482
Ja, das nicht so genau.

01:05:37.062 --> 01:05:41.322
Ich bin mir sicher, dass da ganz, ganz, ganz viele Fragen noch offen sind und dass da ganz, ganz, ganz viele Fragen noch kommen werden.

01:05:41.322 --> 01:05:42.502
aber so. Ich glaube, den...

01:05:42.502 --> 01:05:44.203
Ein bisschen als Einstieg, weil, also ich meine auch,

01:05:44.722 --> 01:05:47.042
mir waren da viele Dinge

01:05:47.042 --> 01:05:48.663
nicht so richtig klar. Also jetzt, nachdem ich den Artikel

01:05:48.663 --> 01:05:50.383
zumindest teilweise so gelesen habe,

01:05:50.542 --> 01:05:53.002
dachte ich, ja, okay, da kann man schon coole Sachen mitmachen

01:05:53.002 --> 01:05:54.422
und vor allen Dingen kann man das auch,

01:05:55.082 --> 01:05:56.862
dass das eben, dass ein Modul auch nur einfach

01:05:56.862 --> 01:05:58.482
ein Objekt ist, das ist irgendwie die Eigenschaft,

01:05:58.643 --> 01:06:00.903
kann man ja eigentlich total gut ausnutzen, um damit

01:06:00.903 --> 01:06:02.282
irgendwie Dinge zu machen.

01:06:03.302 --> 01:06:04.042
Aber sollte man.

01:06:04.102 --> 01:06:05.842
Sollte man vielleicht nicht, aber,

01:06:06.462 --> 01:06:08.982
also zum Beispiel ein tatsächliches Problem,

01:06:09.163 --> 01:06:11.282
wo ich halt auch schon so mit Paketen

01:06:11.282 --> 01:06:13.183
und Dingen rumgespielt habe, wo ich dachte so,

01:06:13.222 --> 01:06:15.102
oh, da gibt es, irgendwie gibt es da keine gute Lösung

01:06:15.102 --> 01:06:17.302
für, aber es wäre schön,

01:06:17.383 --> 01:06:19.183
eine zu haben, ist halt, oder ich weiß nicht, vielleicht kennst du

01:06:19.183 --> 01:06:21.302
eine, ich meine, im Machine Learning-Bereich,

01:06:21.383 --> 01:06:23.042
wenn man da Modelle hat, man trainiert die Modelle

01:06:23.042 --> 01:06:24.842
jetzt aber nicht, also man hat normalerweise ein

01:06:24.842 --> 01:06:27.062
Produktionssystem, was irgendwie dann Dinge

01:06:27.062 --> 01:06:29.022
tut, so mit echten Usern und

01:06:29.022 --> 01:06:30.663
echten Daten und so,

01:06:31.722 --> 01:06:32.342
aber da

01:06:32.342 --> 01:06:35.042
entwickelt man ja nicht und man trainiert ja auch nicht

01:06:35.042 --> 01:06:37.123
die Modelle, sondern Modelle trainierst du dann meistens irgendwie

01:06:37.123 --> 01:06:39.422
in einem Jupyter-Notebook oder so,

01:06:39.703 --> 01:06:40.562
dann hast du da dein Modell

01:06:40.562 --> 01:06:42.942
und jetzt willst du das irgendwie

01:06:42.942 --> 01:06:45.123
aber in deine Produktionsumgebung integrieren.

01:06:46.022 --> 01:06:47.062
Wie machst du das denn? Jetzt kannst du

01:06:47.062 --> 01:06:49.262
natürlich jedes Mal, wenn du dein Modell trainiert hast,

01:06:49.442 --> 01:06:51.203
aber das sind ja oft Dinge, die dann auch periodisch passieren

01:06:51.203 --> 01:06:53.222
und automatisch, kannst du

01:06:53.222 --> 01:06:55.222
ein neues Paket bauen und das dann releasen.

01:06:55.883 --> 01:06:56.922
Aber dieser Deployment-Prozess

01:06:56.922 --> 01:06:58.742
ist halt ziemlich invasiv.

01:07:00.482 --> 01:07:01.322
Vielleicht willst du

01:07:01.322 --> 01:07:03.222
das nicht regelmäßig oder auch nicht automatisch

01:07:03.222 --> 01:07:04.942
machen, weil du brauchst Verbrechtigungen

01:07:04.942 --> 01:07:06.342
auf irgendwelchen Systemen und keine Ahnung.

01:07:06.822 --> 01:07:08.562
Gut, kannst du das natürlich auch, kannst du irgendwie

01:07:08.562 --> 01:07:10.623
Deployment automatisieren, was halt so ein bisschen höhe ist.

01:07:11.562 --> 01:07:12.802
Und du hast dann ganz, ganz

01:07:12.802 --> 01:07:14.562
viele Paketversionen auch

01:07:14.562 --> 01:07:16.082
und es ist halt viel,

01:07:16.942 --> 01:07:18.582
diese Modelle sind halt teilweise sehr riesig.

01:07:20.203 --> 01:07:20.742
Also irgendwie

01:07:20.742 --> 01:07:22.302
ist das nicht so richtig schön und

01:07:22.302 --> 01:07:24.623
das ist halt die Frage, wie macht man das eigentlich ordentlich?

01:07:24.703 --> 01:07:26.442
Und du hast das Problem, wenn man jetzt Sachen pickles,

01:07:26.582 --> 01:07:27.242
zum Beispiel auch,

01:07:28.123 --> 01:07:29.862
dann ist das

01:07:29.862 --> 01:07:32.462
von dem Python-Interpreter abhängig

01:07:32.462 --> 01:07:34.262
und so

01:07:34.262 --> 01:07:36.782
und der ist möglicherweise in diesem

01:07:36.782 --> 01:07:38.502
Jupyter-Notebook-Umfeld, wo jetzt

01:07:38.502 --> 01:07:40.482
Data Sciences, irgendwelche Modelle trainieren, halt auch wieder

01:07:40.482 --> 01:07:42.683
anders, aus speziellen Gründen anders

01:07:42.683 --> 01:07:44.403
als in der

01:07:44.403 --> 01:07:46.322
Produktionsumgebung, wo dann die...

01:07:46.322 --> 01:07:48.742
Und Pickel kann ja selbst auch Imports durchführen.

01:07:48.942 --> 01:07:49.062
Ja.

01:07:50.942 --> 01:07:52.403
Du musst ein bisschen aufpassen, wenn man

01:07:52.403 --> 01:07:54.383
Versionen nimmt oder so, also Sachen pickelt und dann

01:07:54.383 --> 01:07:56.502
Python-Versionen weitergeht, dann geht

01:07:56.502 --> 01:07:58.582
das dann mal kaputt, das heißt, das ist nicht mal so einfach

01:07:58.582 --> 01:08:00.502
dann... Ja, beziehungsweise auch, wenn du andere Imports

01:08:00.502 --> 01:08:02.462
hast oder andere Versionen, Pickel

01:08:02.462 --> 01:08:04.143
importiert halt die Sachen, die es braucht und

01:08:04.143 --> 01:08:04.862
ja.

01:08:06.322 --> 01:08:08.482
Ja, und also das ist

01:08:08.482 --> 01:08:10.383
Das kann schon, also da gibt es

01:08:10.383 --> 01:08:12.422
diverse Fallstricke und der Weg, den ich dann

01:08:12.422 --> 01:08:13.842
irgendwann gegangen bin, ist halt dynamisch

01:08:13.842 --> 01:08:16.322
Conda-Pakete zu bauen und weil das

01:08:16.322 --> 01:08:18.342
mit Conda relativ leicht ging, aber das war

01:08:18.342 --> 01:08:20.342
da kann, ich weiß nicht, ob es da Importlib, doch

01:08:20.342 --> 01:08:22.442
Importlib gab es glaube ich auch schon, ich wusste aber nicht so viel

01:08:22.442 --> 01:08:23.402
davon, ich weiß nicht genau

01:08:23.402 --> 01:08:26.143
und die habe ich dann halt sozusagen als

01:08:26.143 --> 01:08:28.263
Django-Modelle

01:08:28.263 --> 01:08:30.062
irgendwie als Files irgendwo hingelegt und dann

01:08:30.062 --> 01:08:32.382
diese Pakete importiert und dann konnte man einfach

01:08:32.382 --> 01:08:34.303
einfach sozusagen sich, konnte man

01:08:34.303 --> 01:08:36.422
in einem Jupyter-Notepunkt, wenn man ein Modell fertig trainiert hat

01:08:36.422 --> 01:08:38.342
konnte man sagen, deploy mir dieses Modell irgendwie

01:08:38.342 --> 01:08:40.163
und dann tauchte das halt auf

01:08:40.163 --> 01:08:42.163
und wenn man es ausgewählt hat, wurde es halt importiert.

01:08:42.743 --> 01:08:43.902
Und zwar einfach aus...

01:08:43.902 --> 01:08:45.303
Aus der Datenbank importiert.

01:08:45.783 --> 01:08:47.822
Aus der Datenbank, beziehungsweise nicht aus der Datenbank, sondern

01:08:47.822 --> 01:08:49.402
aus der Datenbank plus irgendwie,

01:08:50.102 --> 01:08:52.822
naja, nicht in dem Filesystem, sondern in der Filesystemabstraktion

01:08:52.822 --> 01:08:53.803
im

01:08:53.803 --> 01:08:55.042
Files storage,

01:08:55.322 --> 01:08:56.382
und

01:08:56.382 --> 01:09:00.123
das geht wahrscheinlich auch

01:09:00.123 --> 01:09:01.502
ohne Conda, nehme ich mal an,

01:09:01.723 --> 01:09:03.102
wenn ich das jetzt mir so überlege.

01:09:03.922 --> 01:09:05.862
Und wahrscheinlich geht das auch noch eleganter,

01:09:06.203 --> 01:09:07.442
als wie ich das damals gemacht habe.

01:09:07.442 --> 01:09:24.083
Ja, aber also jetzt mal die Diskussionsfrage, warum nicht wirklich aus der Datenbank importieren? Im Prinzip sind da nur irgendwelche Daten, kannst du da als String da reinlegen und kannst sagen, importiere mir dieses Modell, kannst du ein Reimport machen und dann wirst du vermutlich noch so einen Proxy-Pattern brauchen.

01:09:24.083 --> 01:09:26.822
Ja, also das Ding für

01:09:26.822 --> 01:09:28.703
Conda war dann halt tatsächlich

01:09:28.703 --> 01:09:30.843
irgendwie, was ist, wenn ich jetzt irgendeine spezielle

01:09:30.843 --> 01:09:32.822
Abhängigkeit habe

01:09:32.822 --> 01:09:34.723
in meinem Modell, also ich benutze jetzt irgendeine

01:09:34.723 --> 01:09:36.562
neue fancy Maschine

01:09:36.562 --> 01:09:38.303
in der Bibliothek, die ich auf dem

01:09:38.303 --> 01:09:40.362
Produktionssystem jetzt aber noch nicht habe

01:09:40.362 --> 01:09:42.203
Ja, okay, dann stirbt es ab und

01:09:42.203 --> 01:09:44.482
Genau, und dann ist halt

01:09:44.482 --> 01:09:46.663
kaputt, wie kriege ich das

01:09:46.663 --> 01:09:48.663
da mit rein und zwar ohne, dass ich

01:09:48.663 --> 01:09:50.782
ja, und das war, über Conda ging das

01:09:50.782 --> 01:09:51.123
aber

01:09:51.123 --> 01:09:51.623
Ja, okay.

01:09:52.902 --> 01:09:55.223
Das ist natürlich schwierig, vor allem wenn du dann Sachen installieren

01:09:55.223 --> 01:09:57.203
musst, die du eigentlich, was du an der

01:09:57.203 --> 01:09:59.123
Stelle eigentlich nicht willst. Wobei,

01:09:59.263 --> 01:10:01.042
also ich meine, Pip gibt es auch als Bibliothek.

01:10:01.143 --> 01:10:02.382
Du kannst auch Pip aufrufen

01:10:02.382 --> 01:10:04.623
von Python heraus.

01:10:06.502 --> 01:10:06.623
Also,

01:10:07.042 --> 01:10:09.102
was ich für

01:10:09.102 --> 01:10:09.522
meine

01:10:09.522 --> 01:10:12.902
interaktive Programmierungssache gemacht habe, ist

01:10:12.902 --> 01:10:14.442
eben so ein Proxy-Pattern.

01:10:14.922 --> 01:10:17.102
Dass du quasi

01:10:17.102 --> 01:10:17.962
eine Schicht dazwischen hast.

01:10:17.962 --> 01:10:20.402
weil du möchtest ja

01:10:20.402 --> 01:10:22.203
an der Stelle, wenn du es neu importierst,

01:10:22.282 --> 01:10:24.002
musst du halt auch ganz viele Instanzen ersetzen.

01:10:24.362 --> 01:10:26.322
Eigentlich. Und das ist

01:10:26.322 --> 01:10:28.123
schwierig, weil die hast du oft nicht selber in der Hand

01:10:28.123 --> 01:10:29.723
oder da kommst du oft einfach gar nicht dran.

01:10:29.902 --> 01:10:32.183
Also Instanzen, das heißt, du musst die laden mit dem neuen Kontext

01:10:32.183 --> 01:10:33.822
der neuen Importe. Genau, weil

01:10:33.822 --> 01:10:36.102
du den neuen Code hast und eigentlich

01:10:36.102 --> 01:10:38.102
müsstest du jetzt die... Du musst aber dann quasi ja alle

01:10:38.102 --> 01:10:40.102
Transaktionen, die du auf der einen Instanz hast, schon gemacht hast,

01:10:40.123 --> 01:10:42.402
schon wieder nachvollziehen, weil du den State ja quasi wiederherstellen musst.

01:10:42.422 --> 01:10:44.143
Genau, also genau, das ist die eine Sache,

01:10:44.203 --> 01:10:46.263
du müsstest den State quasi wiederherstellen und die andere

01:10:46.263 --> 01:10:47.902
Sache ist, du müsstest den Code ersetzen, weil

01:10:47.902 --> 01:10:51.303
Ich habe jetzt ja ein m.x und ich möchte aber ein m.x2 haben.

01:10:51.303 --> 01:10:53.102
Aber das kann jetzt ganz anders sein, weil du hast jetzt nur m.

01:10:53.102 --> 01:10:53.763
Ja, genau, kann sein.

01:10:54.542 --> 01:10:57.763
Und dafür gibt es einen Pattern, das heißt Proxy-Pattern,

01:10:57.882 --> 01:11:00.442
wo du quasi ein Interface definierst, was da alles drin ist.

01:11:01.042 --> 01:11:02.042
Was ist denn ein Interface?

01:11:02.203 --> 01:11:06.402
Also du definierst quasi, was ein Objekt kann.

01:11:06.782 --> 01:11:07.422
Also ein Typ.

01:11:07.803 --> 01:11:11.303
Und die eigentliche Umsetzung ist aber quasi eine Klasse dahinter.

01:11:11.623 --> 01:11:13.203
Du definierst quasi den Typ und dann...

01:11:13.203 --> 01:11:16.022
Dieser Proxy macht nichts anderes, als diese Aufrufe weitergeben.

01:11:16.022 --> 01:11:21.582
und dann kannst du nämlich dem Proxy sagen, ersetz mal deinen Background,

01:11:21.822 --> 01:11:26.763
ersetz mal deinen Hintergrund, den Code, ohne den Proxy selbst anfassen zu müssen,

01:11:26.882 --> 01:11:29.843
den du halt oft nicht rauskriegst, weil der in irgendwelchen Sachen drin hängt.

01:11:30.482 --> 01:11:35.582
Und ich könnte mir durchaus vorstellen, dass das mit so Machine Learning Modellen auch funktionieren könnte,

01:11:35.582 --> 01:11:41.402
dass du halt einen Proxy hast, der dieses Modell weg abstrahiert und der kann die Sachen irgendwoher wiederladen,

01:11:41.502 --> 01:11:45.282
ob das jetzt aus der Datenbank ist oder aus dem Dateisystem oder sonst woher.

01:11:46.022 --> 01:11:49.822
einfach, dass du eine Trennungsschicht drin hast.

01:11:50.082 --> 01:11:51.822
Ja, das ist wahrscheinlich auch

01:11:51.822 --> 01:11:53.223
der richtige Weg.

01:11:53.922 --> 01:11:55.223
Das wäre der richtige Weg.

01:11:55.643 --> 01:11:58.082
Ja gut, man weiß das ja

01:11:58.082 --> 01:11:59.362
oft zu dem Zeitpunkt nicht so richtig.

01:11:59.843 --> 01:12:01.782
Es ist einiges an Verwaltungsaufwand,

01:12:02.082 --> 01:12:04.062
so ein Proxy richtig zu machen und

01:12:04.062 --> 01:12:06.022
das geht in manchen Sprachen einfacher.

01:12:06.922 --> 01:12:07.962
Ein Interface definieren geht

01:12:07.962 --> 01:12:10.062
in Java ganz einfach, weil das gibt es da halt.

01:12:10.582 --> 01:12:12.082
In Python ist es halt nur eine Klasse,

01:12:12.082 --> 01:12:13.942
die lauter Not Implemented Errors hat.

01:12:16.022 --> 01:12:17.623
Ja, aber ungefähr so, ja.

01:12:18.843 --> 01:12:19.042
Ja.

01:12:19.382 --> 01:12:19.542
Ja.

01:12:20.062 --> 01:12:24.123
Achso, gibt es zu diesem Projekt, gibt es da eigentlich auch schon einen Link oder sowas?

01:12:24.343 --> 01:12:25.422
Nee, demnächst.

01:12:25.663 --> 01:12:25.922
Demnächst.

01:12:26.502 --> 01:12:27.422
Wird nachgereicht.

01:12:27.522 --> 01:12:28.422
Ich liefere das nach.

01:12:28.683 --> 01:12:29.002
Okay.

01:12:29.163 --> 01:12:31.402
Und jetzt habe ich es öffentlich gesagt, jetzt muss ich es auch wirklich machen.

01:12:31.643 --> 01:12:32.343
Das ist immer gut.

01:12:32.582 --> 01:12:32.902
Sehr schön.

01:12:33.203 --> 01:12:37.482
Ich hatte ja, vielleicht rede ich mich ja noch gegenüber mir selbst, kann ich mich immer

01:12:37.482 --> 01:12:39.402
sehr leicht rausreden, aber wenn ich es jetzt schon gesagt habe.

01:12:39.422 --> 01:12:42.102
Ja, gib mal auf jeden Fall deine Bucketlist, dann erwähnen wir es mal öffentlich.

01:12:42.263 --> 01:12:42.663
Ja, gut.

01:12:42.882 --> 01:12:43.322
Das ist gut.

01:12:43.322 --> 01:12:47.123
Ja, also interessant, dass man aus so einem Blogartikel

01:12:47.123 --> 01:12:49.123
noch alles machen kann. Also wir hatten ja, glaube ich, ja vorher, bevor wir

01:12:49.123 --> 01:12:51.123
einen Blog gefunden hatten, irgendwie, und dann war ja irgendwie

01:12:51.123 --> 01:12:53.282
ergänzte Information. In demselben Blog habe ich

01:12:53.282 --> 01:12:55.203
noch so ein paar andere Sachen entdeckt, die wir auch vorhaben,

01:12:55.362 --> 01:12:57.362
sowas wie Datentypen sprechen und wie das implementiert

01:12:57.362 --> 01:12:59.482
ist und wie halt das Python-Objekt-System

01:12:59.482 --> 01:13:01.303
funktioniert oder die einzelnen Dinge oder

01:13:01.303 --> 01:13:03.362
der C-Python-Compiler,

01:13:03.522 --> 01:13:05.343
wie das überhaupt geht. Und da müssen wir auf jeden Fall

01:13:05.343 --> 01:13:07.163
auch mal drüber sprechen. Aber schaut doch schon mal

01:13:07.163 --> 01:13:09.102
in diesen Blog rein, 10.000 Meters Com, das fand ich wirklich

01:13:09.102 --> 01:13:10.703
interessant. Ja, da waren einige gute Sachen dabei.

01:13:10.703 --> 01:13:11.042
Ja, ziemlich.

01:13:11.042 --> 01:13:14.322
Ja, ich habe mir auch dieses

01:13:14.322 --> 01:13:16.303
C-Python-Internalist-Buch

01:13:16.303 --> 01:13:17.223
besorgt.

01:13:19.723 --> 01:13:20.002
Ja,

01:13:20.263 --> 01:13:22.402
mal schauen.

01:13:22.602 --> 01:13:23.843
Vielleicht kann man da auch noch ein bisschen was rausholen.

01:13:23.922 --> 01:13:25.522
Ja, das werden wir auf jeden Fall, also vielleicht

01:13:25.522 --> 01:13:27.223
verpusten wir jetzt tatsächlich so jeden dieser Blogposts.

01:13:29.362 --> 01:13:31.482
Wir lesen die einfach vor.

01:13:32.723 --> 01:13:34.002
Nein, das ist wirklich toll und ich glaube,

01:13:34.123 --> 01:13:35.962
dass viel, was auch Hörer von uns gerne

01:13:35.962 --> 01:13:37.623
interessiert und wissen wollen, was da irgendwie so passiert,

01:13:37.723 --> 01:13:39.902
dass man so ein bisschen darüber redet, weil das machen wir ja.

01:13:39.962 --> 01:13:40.922
So ein bisschen erklären, wie Python

01:13:40.922 --> 01:13:43.062
als Sprache und so.

01:13:43.703 --> 01:13:44.902
Ja, auch.

01:13:46.002 --> 01:13:46.643
Ja, spannend.

01:13:47.022 --> 01:13:48.743
Ja, super. Ich glaube, wir haben

01:13:48.743 --> 01:13:50.102
über Impulse gar nicht mehr so viel zu sagen.

01:13:50.602 --> 01:13:52.683
Ich habe gehört, Johannes hat sich extra einen Pick der Woche überlegt.

01:13:52.822 --> 01:13:55.143
Ich habe mir tatsächlich einen Pick

01:13:55.143 --> 01:13:57.062
und zwar GitHub Octo.

01:13:59.683 --> 01:14:00.723
Das ist eine

01:14:00.723 --> 01:14:02.602
Anwendung, die GitHub geschrieben hat,

01:14:03.402 --> 01:14:05.402
mit der man Repositories

01:14:05.402 --> 01:14:07.243
visualisieren kann.

01:14:07.243 --> 01:14:09.422
Also die interne Struktur des Codes

01:14:09.422 --> 01:14:10.723
in einem Repository.

01:14:10.922 --> 01:14:13.763
so der Hintergrund ist

01:14:13.763 --> 01:14:16.102
du kommst in ein neues Projekt rein

01:14:16.102 --> 01:14:18.062
und da sind jetzt eine Million

01:14:18.062 --> 01:14:19.183
Teilen Python-Code drin

01:14:19.183 --> 01:14:21.442
und deine erste Aufgabe ist

01:14:21.442 --> 01:14:23.482
mach mal hier eine Log-Ausgabe rein

01:14:23.482 --> 01:14:27.982
es ist sehr schwer

01:14:27.982 --> 01:14:30.263
sich da zurechtzufinden und es ist auch sehr schwer

01:14:30.263 --> 01:14:32.282
Sachen zu finden in Projekten

01:14:32.282 --> 01:14:34.203
wenn man sie nicht sehr genau

01:14:34.203 --> 01:14:35.982
kennt und da ist eben GitHub

01:14:35.982 --> 01:14:37.502
Octor, das macht hier so ein paar sehr schöne

01:14:37.502 --> 01:14:40.062
Grafen, das zeigt quasi grafisch

01:14:40.062 --> 01:14:45.643
und ich kann es jetzt mal ins Bild halten hier, zeigt quasi grafisch die Abhängigkeiten

01:14:45.643 --> 01:14:50.263
zwischen den verschiedenen Dateien, wo die liegen und wer sich importiert und wie die

01:14:50.263 --> 01:14:53.922
aufeinander aufbauen und dann kann man eben sehr schnell da so einen Überblick bekommen

01:14:53.922 --> 01:14:57.102
darüber, was mit was interagiert und was wohin gehört.

01:14:57.402 --> 01:15:00.683
Also schöne Kreisbeispiele hier zeigen.

01:15:00.703 --> 01:15:02.542
Wundervoll, das sieht ja richtig kreativ aus.

01:15:02.542 --> 01:15:04.163
Es sieht richtig schön aus.

01:15:04.343 --> 01:15:05.942
Zum Ausdruck an die Wand hängen, also als Kunst jetzt.

01:15:05.942 --> 01:15:26.263
Ja, zum einen das und zum anderen auch funktionale Kunst, wo man eben nachsehen kann, von wo nach wo man hin navigieren muss. Und auch interessant, weil es eben so auf eine gewisse Art und Weise die Architektur einer Software widerspiegelt, die ja sehr unterschiedlich sein kann. Also wenn man sich hier diese Screenshots anschaut, die sind ja zum Teil sehr unterschiedlich. Manche sind halt sehr flache Hierarchien.

01:15:26.263 --> 01:15:27.042
Die Screenshots werden wir auch nehmen.

01:15:27.303 --> 01:15:28.542
Sehr breit, selbstverständlich.

01:15:30.143 --> 01:15:32.462
Und manche sind sehr gut aufgeteilt. Da sieht man vielleicht auch so ein bisschen den Style.

01:15:32.462 --> 01:15:34.743
Genau, also es ist wirklich einfach

01:15:34.743 --> 01:15:36.862
eine Einsicht, die man sonst nur sehr schwer

01:15:36.862 --> 01:15:38.803
kriegen kann. Oder auch hier, also

01:15:38.803 --> 01:15:39.303
hier gibt es eins,

01:15:39.602 --> 01:15:44.663
wo man eben sieht, dass

01:15:44.663 --> 01:15:46.763
jedes Paket quasi gleich ist und jedes Paket

01:15:46.763 --> 01:15:48.683
hat auch so eine Testpunkt-Pi drin und das sind eben

01:15:48.683 --> 01:15:50.382
halt diese grünen Punkte hier und man sieht, okay,

01:15:50.482 --> 01:15:52.522
jedes Paket hat eins. Oder in einem anderen

01:15:52.522 --> 01:15:54.482
Projekt sind die grünen Punkte halt alle in einem

01:15:54.482 --> 01:15:55.743
großen Modul drin und

01:15:55.743 --> 01:15:58.462
man sieht, okay, die sind nebendran, die sind offenbar nicht

01:15:58.462 --> 01:16:00.522
integriert. Also es gibt einfach sehr

01:16:00.522 --> 01:16:02.163
schnell einen Überblick über die Struktur

01:16:02.163 --> 01:16:04.382
eines Projektes, was so an sich

01:16:04.382 --> 01:16:06.683
nicht so einfach zu finden ist.

01:16:08.082 --> 01:16:08.683
Das ist mein Pick

01:16:08.683 --> 01:16:09.183
für diese Woche.

01:16:09.683 --> 01:16:12.163
Ich würde picken Oh My Git.

01:16:13.183 --> 01:16:14.623
Das ist ein Spiel,

01:16:14.882 --> 01:16:15.703
wenn man Git lernen will.

01:16:15.882 --> 01:16:16.362
Oh My Git?

01:16:17.862 --> 01:16:19.703
Ich weiß gar nicht, was daraus geschrieben wurde.

01:16:20.582 --> 01:16:22.382
Aber man kann es halt damit Git spielen

01:16:22.382 --> 01:16:23.843
mit so Cards und lernt so ein bisschen über Git.

01:16:23.982 --> 01:16:26.282
Natürlich auch so Beginner-Level und so, aber das ist halt

01:16:26.282 --> 01:16:28.282
relativ spannend, wenn man so ein bisschen Advanced-Git

01:16:28.282 --> 01:16:30.243
noch machen will. Also, wenn es nicht jetzt

01:16:30.243 --> 01:16:32.362
Rebase Interactive und dann irgendwie gucken will,

01:16:32.442 --> 01:16:34.062
dass man irgendwelche Commits stasht, dass man irgendwie

01:16:34.062 --> 01:16:35.922
dann doch irgendwie die Message ändern und

01:16:35.922 --> 01:16:38.343
was man da nicht so alles machen kann, so ein bisschen zu verstehen,

01:16:38.422 --> 01:16:40.382
was das überhaupt ist. Cool, hört sich

01:16:40.382 --> 01:16:42.143
aufspannend an. Sehr nice, ja, also

01:16:42.143 --> 01:16:44.482
Gamification mit GIT

01:16:44.482 --> 01:16:46.183
halt als kleines Spielchen ist schon irgendwie cool.

01:16:46.703 --> 01:16:48.422
GITification. Ja, man sieht halt

01:16:48.422 --> 01:16:50.462
auch immer ein bisschen visualisiert und man kann da so Sachen klicken

01:16:50.462 --> 01:16:52.082
und das ist irgendwie ganz nett, also weil

01:16:52.082 --> 01:16:54.362
ich meine, so Bratis oder so, jemand, der so ein bisschen programmiert

01:16:54.362 --> 01:16:56.163
oder hat das ja irgendwann schon mal gesehen oder

01:16:56.163 --> 01:16:58.343
viele Leute haben halt dann GIT nur zum

01:16:58.343 --> 01:16:59.482
Push oder Pullen verwendet irgendwann.

01:16:59.982 --> 01:17:01.602
Man kann echt tolle Sachen mitmachen.

01:17:01.843 --> 01:17:02.362
Also spannende Sachen.

01:17:04.042 --> 01:17:05.723
Deswegen ist es interessant, um so ein bisschen

01:17:05.723 --> 01:17:07.002
Advanced dann auch zu machen.

01:17:07.243 --> 01:17:08.922
Und geht ja auch in die gleiche Richtung. Ist ja spannend.

01:17:09.723 --> 01:17:10.862
Ähnliche Picks haben die so.

01:17:11.982 --> 01:17:14.382
Ja, hat auch was mit Git zu tun.

01:17:15.822 --> 01:17:16.183
Lustigerweise.

01:17:17.343 --> 01:17:18.462
Ja, auch bei dem

01:17:18.462 --> 01:17:20.322
Backtail-Media-Pull-Request

01:17:20.322 --> 01:17:22.243
ist mir das dann untergekommen,

01:17:22.902 --> 01:17:23.882
weil

01:17:23.882 --> 01:17:26.422
ich hatte halt gar nicht

01:17:26.422 --> 01:17:27.962
gesehen, dass da irgendwelche

01:17:27.962 --> 01:17:31.643
und normalerweise hat man immer so Linting-Steps oder so,

01:17:31.723 --> 01:17:34.862
wo man jetzt irgendwie Software testet oder so.

01:17:34.962 --> 01:17:35.703
Das war da jetzt gar nicht.

01:17:35.782 --> 01:17:37.123
Da dachte ich mir, das ist schon mal ein bisschen komisch.

01:17:37.502 --> 01:17:40.862
Und dann hat irgendwie bei GitHub,

01:17:41.082 --> 01:17:42.522
hat dann irgendwie das Ding mich angemerkt,

01:17:42.663 --> 01:17:44.082
hat so, dein Code ist ja irgendwie,

01:17:44.143 --> 01:17:45.902
da sind ja die ganzen Linting-Geschichten nicht richtig

01:17:45.902 --> 01:17:47.663
und da ist noch was falsch und es ist falsch.

01:17:47.763 --> 01:17:49.623
Du warst schon überrascht, weil du hattest doch gemacht,

01:17:49.743 --> 01:17:50.542
was da drin definiert ist.

01:17:50.562 --> 01:17:52.782
Genau, und ich dachte schon so, ja gut, so mache ich das halt,

01:17:52.822 --> 01:17:53.982
das ist doch normal und das ist doch okay.

01:17:54.643 --> 01:17:56.402
Und dann dachte ich so, ja, wie passiert das eigentlich,

01:17:56.402 --> 01:17:58.102
das GitHub das weiß, dass das nicht okay ist

01:17:58.102 --> 01:18:00.183
und ja, dann wurde ich

01:18:00.183 --> 01:18:01.882
auch darauf hingewiesen, so, ja

01:18:01.882 --> 01:18:03.843
wir benutzen hier Precommit

01:18:03.843 --> 01:18:05.683
benutzen das auch mal auch

01:18:05.683 --> 01:18:08.102
und das ist auch ein ganz

01:18:08.102 --> 01:18:09.862
das ist glaube ich auch noch ein Projekt von Anthony

01:18:09.862 --> 01:18:11.663
Soti, ich weiß gar nicht, wie man den ausspricht

01:18:11.663 --> 01:18:13.843
und

01:18:13.843 --> 01:18:16.163
man definiert das quasi in so

01:18:16.163 --> 01:18:18.082
einer Art Konfigurationsdatei

01:18:18.082 --> 01:18:19.442
was man da gerne hätte

01:18:19.442 --> 01:18:21.902
und dann sagt man Precommit

01:18:21.902 --> 01:18:23.962
Install oder so und dann installiert

01:18:23.962 --> 01:18:25.703
es alle Abhängigkeiten, die man braucht, um diese

01:18:25.703 --> 01:18:27.123
Geschichten machen zu können lokal,

01:18:27.743 --> 01:18:29.843
aber man muss diese Abhängigkeiten dann auch nicht mehr

01:18:29.843 --> 01:18:31.822
im Projekt haben. Man hat ja normalerweise auch mal so eine ganze

01:18:31.822 --> 01:18:33.683
Reihe von Dingen, ja, was weiß ich nicht,

01:18:33.723 --> 01:18:35.743
Black, Flag8, dieses ganze

01:18:35.743 --> 01:18:37.703
Zeugs, auch im gleichen Projekt

01:18:37.703 --> 01:18:39.282
dann immer rumhängen und...

01:18:39.282 --> 01:18:41.243
Das ist Death Dependencies quasi, Herr Sotz, oder?

01:18:42.522 --> 01:18:43.803
Ne, ist nicht Death Dependencies.

01:18:43.902 --> 01:18:45.803
Death Dependencies sind ja auch nochmal andere Sachen,

01:18:45.942 --> 01:18:47.723
aber man hat halt diesen Kram dann da nicht

01:18:47.723 --> 01:18:49.223
mehr drin, sondern das, ich weiß gar nicht,

01:18:49.442 --> 01:18:50.763
dass ein eigenes Virtual

01:18:50.763 --> 01:18:53.683
Environment installiert wird, ich weiß jetzt gar nicht genau,

01:18:53.743 --> 01:18:55.643
wie es dann technisch funktioniert. Auf jeden Fall

01:18:55.643 --> 01:18:57.862
ist es dann so, wenn man sagt, dann git commit oder so,

01:18:58.042 --> 01:18:59.782
dann läuft das dann halt automatisch

01:18:59.782 --> 01:19:01.562
durch und wenn

01:19:01.562 --> 01:19:02.462
es nicht

01:19:02.462 --> 01:19:05.663
richtig war, dann sagt es irgendwie, nee, kann ich

01:19:05.663 --> 01:19:07.542
committen, weil da ist halt zum Beispiel irgendwie noch

01:19:07.542 --> 01:19:09.382
ein, da ist ein

01:19:09.382 --> 01:19:11.482
Plague 8 hat mir gesagt, da ist was faul oder

01:19:11.482 --> 01:19:13.382
es sortiert hier halt einfach mal die Imports um mit

01:19:13.382 --> 01:19:14.822
iSort oder es macht halt irgendwie

01:19:14.822 --> 01:19:17.582
Man kann dann eigene Regeln anlegen, also jedes Mal muss man

01:19:17.582 --> 01:19:19.362
über Droba was machen, ja okay. Genau.

01:19:19.743 --> 01:19:20.683
Der Dockstring ist nicht lang genug.

01:19:22.163 --> 01:19:23.542
Ja, also das

01:19:23.542 --> 01:19:24.843
kannst du halt konfigurieren, wie du willst, aber

01:19:24.843 --> 01:19:26.442
Es wird dann halt auch so mal

01:19:26.442 --> 01:19:27.643
ein Comment gemacht.

01:19:27.862 --> 01:19:30.183
Das ist natürlich auch ein bisschen hart.

01:19:30.843 --> 01:19:31.243
Ja, klar.

01:19:31.422 --> 01:19:33.042
Das ist ja schon mal super.

01:19:35.163 --> 01:19:36.902
Das kann man ja relativ leicht hinfaken.

01:19:37.002 --> 01:19:37.282
Ja, genau.

01:19:39.282 --> 01:19:41.143
Aber das fällt ja schon mal auf, wenn er nicht da ist, zum Beispiel.

01:19:41.522 --> 01:19:43.102
Ja, es ist natürlich relativ hart, aber es ist ja

01:19:43.102 --> 01:19:44.303
eigentlich schon auch der richtige Zeitpunkt.

01:19:44.982 --> 01:19:46.982
Du kannst nicht committen, ohne dass alles in Ordnung ist.

01:19:47.482 --> 01:19:48.982
Genau, das heißt, es ist damit sichergestellt,

01:19:49.062 --> 01:19:50.382
dass nicht irgendwelcher Quatsch da drin ist.

01:19:50.482 --> 01:19:52.042
Wahrscheinlich kann man das dann auch irgendwie umgehen.

01:19:52.163 --> 01:19:53.382
Ist das eine Library oder was?

01:19:53.382 --> 01:19:54.163
oder ist das...

01:19:54.163 --> 01:19:56.803
Ja, das ist ein Projekt, das ist auch ein Kommando-Zeilentool.

01:19:58.322 --> 01:19:59.223
Man benutzt es als

01:19:59.223 --> 01:20:00.683
Kommando-Zeilentool und man sagt im Grunde einmal

01:20:00.683 --> 01:20:03.002
pre-commit install und dann guckt es halt in diese

01:20:03.002 --> 01:20:04.962
Konfigurationsdateien, macht seine Magie

01:20:04.962 --> 01:20:07.522
und danach sind diese Git-Hooks

01:20:07.522 --> 01:20:07.843
gesetzt.

01:20:08.102 --> 01:20:10.703
Das muss man quasi bei jedem Dev erstmal einmal installieren, damit das funktioniert.

01:20:10.982 --> 01:20:11.502
Ja, okay.

01:20:14.082 --> 01:20:14.482
Spannend.

01:20:14.962 --> 01:20:16.123
Ja, fand ich auch gut.

01:20:16.442 --> 01:20:19.062
Dann sind wir heute durch mit dem Thema

01:20:19.062 --> 01:20:20.442
und vielen Dank, dass ihr uns wieder dazugehört habt.

01:20:20.442 --> 01:20:22.382
Und egal wo ihr seid, morgens, mittags, abends, nachts

01:20:22.382 --> 01:20:24.402
und bleibt uns gewogen, hört uns gerne

01:20:24.402 --> 01:20:26.703
wieder, schaltet wieder rein und euch noch einen schönen

01:20:26.703 --> 01:20:28.102
was auch immer Tag, Nacht,

01:20:28.263 --> 01:20:30.062
bis demnächst.

01:20:30.362 --> 01:20:31.143
Alles klar, bis demnächst.
