WEBVTT

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

00:00:05.120 --> 00:00:06.480
Die hatten wir letztes Mal ausweisend ausgelassen.

00:00:07.160 --> 00:00:08.780
Deswegen müssen wir die Episodenummer jetzt ergänzen.

00:00:09.460 --> 00:00:11.520
Ja, was machen wir heute? Wir wollen heute über Imports reden.

00:00:12.060 --> 00:00:12.460
Hi Jochen.

00:00:13.020 --> 00:00:14.320
Ja, hallo. Willkommen Dominik.

00:00:14.900 --> 00:00:15.440
Hi Johannes.

00:00:15.760 --> 00:00:16.920
Ja, hallo. Ich bin auch mal wieder da.

00:00:17.400 --> 00:00:18.200
Ja, wir kennen uns ja alle schon.

00:00:18.720 --> 00:00:20.980
Ja, also über das Python-Import-System wollen wir heute sprechen.

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

00:00:23.380 --> 00:00:25.140
Und dann gehen wir so ein bisschen in die Details.

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

00:00:27.900 --> 00:00:37.720
Ja, also die einzigen News, die ich habe, ist, dass Apple sich gerade den größten PR-Unfug aller Zeiten einholt. Aber da ich kein Apple-Gerät habe, geht es so ein kleines bisschen mehr vorbei.

00:00:37.720 --> 00:00:38.800
Ja, das Problem habe ich auch nicht.

00:00:39.640 --> 00:00:41.460
Jochen, erzähl du doch mal, wie fühlt sich das für dich an?

00:00:42.440 --> 00:00:50.220
Ja, nee, tatsächlich ist es PR-technisch, würde ich sagen, auch aus meiner Perspektive ein großer Unfall. Wenn man sich jetzt anguckt, was sie technisch tun, ist es nicht so furchtbar schlimm.

00:00:50.220 --> 00:00:52.960
Was ist denn überhaupt passiert? Vielleicht erstmal so die Story.

00:00:55.060 --> 00:00:56.540
War das eine Pressemeldung?

00:00:57.020 --> 00:00:59.180
Es war eine Pressemeldung und es war eine technische

00:00:59.180 --> 00:01:00.920
Meldung, glaube ich, dass sie jetzt

00:01:00.920 --> 00:01:02.220
CSAM angemacht haben,

00:01:02.380 --> 00:01:03.920
Content Scanning.

00:01:05.340 --> 00:01:07.720
keine Ahnung, was das bedeutet.

00:01:09.100 --> 00:01:10.140
Ja, jedenfalls wollen sie,

00:01:10.760 --> 00:01:13.160
jedenfalls will Apple jetzt in die Fotos reingucken

00:01:13.160 --> 00:01:15.020
und verbotene

00:01:15.020 --> 00:01:15.580
Inhalte finden.

00:01:16.480 --> 00:01:17.960
Ja, das ist natürlich so ein bisschen,

00:01:18.700 --> 00:01:20.920
das, ja. Mit modernster Technologie.

00:01:21.060 --> 00:01:22.600
Ja, zum Glück

00:01:22.600 --> 00:01:24.220
ist es nicht das

00:01:24.220 --> 00:01:26.260
schlimme Technologie, was

00:01:26.260 --> 00:01:27.620
man halt auch nehmen könnte, aber

00:01:27.620 --> 00:01:30.360
es ist halt irgendwas total Billiges, einfach nur

00:01:30.360 --> 00:01:32.380
Hashes in Bildern angucken. Also im Grunde nur gucken,

00:01:33.000 --> 00:01:34.460
ist das ein Bild, das auf

00:01:34.460 --> 00:01:36.300
irgendeiner Liste draufsteht von verbotenen

00:01:36.300 --> 00:01:38.440
Bildern. Ja, aber haben die nicht auch gesagt,

00:01:38.560 --> 00:01:40.380
dass sie so neuronale Netze

00:01:40.380 --> 00:01:42.460
drüberlaufen lassen und dann Sachen erkennen wollen?

00:01:43.440 --> 00:01:44.440
Oder ist das erst der

00:01:44.440 --> 00:01:46.580
nächste Schritt? Ja, genau, das ist

00:01:46.580 --> 00:01:48.200
halt der Agau-Teil.

00:01:48.260 --> 00:01:50.180
Und das ist auch so ein bisschen der Präzedenzfall.

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

00:01:52.800 --> 00:01:54.840
ja, es ist auf deinem Gerät und es ist alles sicher

00:01:54.840 --> 00:01:55.600
und wir können da gar nicht.

00:01:55.660 --> 00:01:57.200
Und jetzt ist es so, ja, wir gucken doch mal rein.

00:01:58.320 --> 00:02:00.780
Ja, also entweder war es ein Unfall,

00:02:02.000 --> 00:02:03.400
sozusagen, dass jemand nicht drüber nachgedacht hat,

00:02:03.700 --> 00:02:04.700
dass wenn man das so sagt,

00:02:04.780 --> 00:02:06.820
dass das dann genau das auslöst bei den Leuten.

00:02:07.560 --> 00:02:08.780
Oder es ist halt irgendwie,

00:02:08.840 --> 00:02:09.780
aber das kann ich mir auch nicht vorstellen,

00:02:09.860 --> 00:02:12.560
weil das wäre ja so ein abrupter Strategiewechsel.

00:02:12.740 --> 00:02:13.820
Das wäre auch schon irgendwie komisch.

00:02:13.960 --> 00:02:15.340
Also insofern nehme ich mal an,

00:02:15.420 --> 00:02:16.600
dass es eher ein PR-Unfall ist.

00:02:17.080 --> 00:02:18.700
Aber man weiß es nicht.

00:02:18.780 --> 00:02:19.800
Aber es ist ein Präzedenzfall,

00:02:19.980 --> 00:02:22.220
dass Apple scannt jetzt Inhalte auf euren Geräten.

00:02:22.300 --> 00:02:24.140
Vielleicht ist das die Vorbereitung dafür, dass sie auch in China den Markt

00:02:24.140 --> 00:02:26.340
weiter öffnen wollen. Das machen sie ja auch

00:02:26.340 --> 00:02:28.740
sowieso schon immer. Also man kann ja auch in der

00:02:28.740 --> 00:02:30.460
Fotos-App irgendwie nach, weiß ich nicht,

00:02:30.480 --> 00:02:32.380
Hund gucken oder nach Personen oder sonst irgendwas.

00:02:32.900 --> 00:02:34.520
Und da ist tatsächlich, das ist halt

00:02:34.520 --> 00:02:36.460
die gute Technik sozusagen, die da

00:02:36.460 --> 00:02:37.360
verwendet wird und

00:02:37.360 --> 00:02:40.460
man kann sogar... Aber auch da sind viele

00:02:40.460 --> 00:02:42.400
Sachen falsch einsortiert. Ja, aber

00:02:42.400 --> 00:02:44.440
sie sind da auch halbwegs schnell und so. Man kann

00:02:44.440 --> 00:02:46.300
auch nach Vaccination oder so suchen und dann

00:02:46.300 --> 00:02:48.280
findet es den Impfpass, wenn man den fotografiert hat und so.

00:02:48.720 --> 00:02:50.400
Also das ist tatsächlich, also da machen

00:02:50.400 --> 00:02:51.520
sie auch wirklich das gute Zeug.

00:02:52.300 --> 00:02:54.640
und machen das halt auf dem Gerät selber.

00:02:55.800 --> 00:02:59.020
Aber genau, nur halt, wenn man selber sagt, man hätte das gern

00:02:59.020 --> 00:03:02.120
und halt, es wird auch nicht an irgendwen geschickt.

00:03:02.540 --> 00:03:03.600
Und jetzt ist das natürlich eine andere Sache,

00:03:03.660 --> 00:03:05.620
wenn es jetzt eines von den verbotenen Bildern findet,

00:03:05.720 --> 00:03:07.340
dann sagt es irgendwie dem Pets, dass das ...

00:03:07.340 --> 00:03:08.320
Das sind die leicht verbotenen Bilder?

00:03:08.920 --> 00:03:10.280
Ja, wer weiß.

00:03:10.280 --> 00:03:11.140
Mit den False Positives?

00:03:11.180 --> 00:03:13.060
Genau, und wir wissen auch, dass es da welche gibt, ja.

00:03:13.960 --> 00:03:15.540
Also das ist natürlich alles sehr unangenehm

00:03:15.540 --> 00:03:18.320
und das wäre dann schon ein Präsenzfall,

00:03:18.440 --> 00:03:19.780
weil das haben sie bisher nicht gemacht, ja.

00:03:20.700 --> 00:03:21.900
Na gut, mal sehen, wie sich das entwickelt.

00:03:22.000 --> 00:03:23.240
PR-mäßig ist es auf jeden Fall

00:03:23.240 --> 00:03:26.040
ein mittleres Desaster. Du hast das von deinem Impfpass gesagt,

00:03:26.120 --> 00:03:28.180
das heißt, du bist auch jetzt durch, endlich, vielleicht.

00:03:28.200 --> 00:03:29.460
Ich bin schon lange durch.

00:03:29.760 --> 00:03:30.900
Ich auch jetzt seit einer Woche, yay!

00:03:32.120 --> 00:03:34.140
Also hier auch nochmal der Aufruf von

00:03:34.140 --> 00:03:35.380
allen Zuhörern, lasst euch bitte impfen.

00:03:36.220 --> 00:03:38.220
Ja, das ist eine gute Idee. Wie viele haben wir jetzt verloren?

00:03:38.940 --> 00:03:39.420
Ach, egal.

00:03:40.520 --> 00:03:42.200
Die Zuhörer will ich machen. Es gab so einen tollen

00:03:42.200 --> 00:03:43.560
Rant-Post von

00:03:43.560 --> 00:03:45.880
Linus Torweister, glaube ich auch.

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

00:03:49.380 --> 00:03:49.680
Ja, genau.

00:03:49.920 --> 00:03:54.540
Ja, Linus Torvalds benutzt noch mehr

00:03:54.540 --> 00:03:56.340
ausgewählte Wörter, um das

00:03:56.340 --> 00:03:58.000
zu beschreiben, sagen wir es mal so.

00:03:59.440 --> 00:04:00.480
Ja, aber inhaltlich doch.

00:04:00.840 --> 00:04:02.220
Inhaltlich war es die Zusammenfassung, ja.

00:04:02.480 --> 00:04:03.460
Ja, haben wir noch Python-News?

00:04:03.920 --> 00:04:06.580
Ja, also eine News,

00:04:06.660 --> 00:04:07.640
die so ein bisschen anschließt an

00:04:07.640 --> 00:04:10.060
unsere letzte Episode zu Packaging,

00:04:10.720 --> 00:04:12.000
ist, dass tatsächlich, das

00:04:12.000 --> 00:04:14.460
war sich vielleicht schon länger klar, aber mir war es halt noch nicht

00:04:14.460 --> 00:04:16.960
klar, ab Python 3.11

00:04:16.960 --> 00:04:18.400
wird

00:04:18.400 --> 00:04:20.120
Distutils halt deprecated.

00:04:21.720 --> 00:04:22.120
Und

00:04:22.120 --> 00:04:24.780
das heißt, man muss sich da an der Stelle dann halt mal

00:04:24.780 --> 00:04:26.300
was überlegen, was man dann so tut.

00:04:27.060 --> 00:04:28.880
Aber es gibt doch so viele Alternativen.

00:04:29.980 --> 00:04:30.260
Ja.

00:04:30.480 --> 00:04:31.660
Diverse Alternativen.

00:04:32.100 --> 00:04:34.840
Also die Pakete, die jetzt halt so

00:04:34.840 --> 00:04:36.720
ein richtiges Problemchen bekommen,

00:04:37.240 --> 00:04:38.500
sind halt sowas wie

00:04:38.500 --> 00:04:40.640
NumPy und SciPy und so,

00:04:40.940 --> 00:04:42.800
weil die haben nämlich, die erben

00:04:42.800 --> 00:04:44.820
nämlich von Distutils und haben da Extensions

00:04:44.820 --> 00:04:46.240
für gebaut und damit bauen sie halt alles.

00:04:46.800 --> 00:04:47.180
Ja, okay.

00:04:47.460 --> 00:04:48.980
Und ja,

00:04:49.320 --> 00:04:51.000
also die gucken sich gerade andere Sachen an

00:04:51.000 --> 00:04:52.660
und

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

00:04:54.960 --> 00:04:56.560
C-Mac angeguckt oder halt auch

00:04:56.560 --> 00:04:58.220
Mason, heißt das irgendwie.

00:04:59.320 --> 00:05:00.660
Und tatsächlich,

00:05:01.460 --> 00:05:03.040
also ich manchmal, also sogar relativ

00:05:03.040 --> 00:05:05.120
häufig, ich habe ja hier so ein M1-Mac

00:05:05.120 --> 00:05:07.060
auch und da passiert

00:05:07.060 --> 00:05:09.040
das 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.640
Projekte habe, die

00:05:12.640 --> 00:05:14.460
abhängig haben zu NumPy,

00:05:14.640 --> 00:05:16.660
oder so, dass das Ganze zwar kopiert werden muss,

00:05:17.140 --> 00:05:21.680
weil meistens ist das Update von Python halt schneller bei mir,

00:05:21.840 --> 00:05:23.380
als die Wheels draußen sind.

00:05:24.080 --> 00:05:25.440
Und dann muss ich das halt kompilieren

00:05:25.440 --> 00:05:26.500
und dann denke ich mir so, oh nein,

00:05:26.680 --> 00:05:27.820
ah, jetzt dauert das wieder ein paar Minuten.

00:05:28.580 --> 00:05:30.900
Und tatsächlich dauert das bei NumPy, glaube ich,

00:05:30.980 --> 00:05:33.600
sieben Minuten irgendwie mit dem klassischen jetzt des Tutels.

00:05:34.580 --> 00:05:36.880
Und tatsächlich aber auf Mason basierten,

00:05:37.440 --> 00:05:39.280
hat hier jemand schon den Namen vergessen,

00:05:39.580 --> 00:05:40.980
angefangen damit rumzuexperimentieren,

00:05:41.300 --> 00:05:42.940
dauert es halt irgendwie noch vier Sekunden oder so.

00:05:42.940 --> 00:05:46.060
Also es ist hauptsächlich irgendwie Bauzeit.

00:05:47.140 --> 00:05:48.180
die da

00:05:48.180 --> 00:05:50.660
benötigt wird.

00:05:51.420 --> 00:05:52.540
Also insofern, mal gucken.

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

00:05:55.520 --> 00:05:56.940
Das wäre auch ein sehr positiver

00:05:56.940 --> 00:05:58.600
Effekt von dieser Deplication.

00:05:59.460 --> 00:06:01.040
Genau. Und ansonsten,

00:06:01.100 --> 00:06:02.780
ja, ich glaube, 3.11

00:06:02.780 --> 00:06:03.380
ist in der Beta.

00:06:04.800 --> 00:06:05.780
3.10 ist in der Beta.

00:06:06.940 --> 00:06:08.840
Ich glaube, jetzt um den Dreh

00:06:08.840 --> 00:06:09.960
ein Richtkandidat oder was.

00:06:10.960 --> 00:06:12.440
Die Zahlen, die gehen so schnell hoch.

00:06:12.960 --> 00:06:14.340
Ja, ja. Freuen wir uns schon.

00:06:15.300 --> 00:06:16.780
Also ich habe mal den GitHub

00:06:16.780 --> 00:06:18.540
Copilot, den wir auch schon mal kurz erwähnt hatten,

00:06:18.700 --> 00:06:20.720
ausprobiert. Da habe ich jetzt auch eine Beta-Einladung

00:06:20.720 --> 00:06:22.420
bekommen. Ich muss sagen, das ist echt

00:06:22.420 --> 00:06:24.880
toll. Also ich habe noch nie so einen

00:06:24.880 --> 00:06:26.540
super Effekt von einer KI erlebt.

00:06:26.720 --> 00:06:28.440
Ich finde es echt nice. Ich gebe ein,

00:06:28.620 --> 00:06:30.480
also ich habe jetzt die VS Code Extension dafür benutzt.

00:06:30.820 --> 00:06:32.580
Sowas wie Define and Fibonacci

00:06:32.580 --> 00:06:33.400
oder sowas. Und dann

00:06:33.400 --> 00:06:36.500
warte ich auf das Autocompletion und dann schreibt

00:06:36.500 --> 00:06:38.420
mir die komplette Funktion inklusive Docstrings und Type

00:06:38.420 --> 00:06:40.700
Annotations als TypeHint und ich drücke

00:06:40.700 --> 00:06:41.960
einmal Tabulator und es ist fertig.

00:06:42.460 --> 00:06:44.380
Und das geht halt auch für Sachen, die ich selber schreibe.

00:06:44.380 --> 00:06:46.180
Wenn ich jetzt eine Klasse schreibe, verschiedene Methoden nehme,

00:06:46.400 --> 00:06:48.780
beispielsweise irgendwie HTTP-Methode.

00:06:48.840 --> 00:06:49.860
Ich habe jetzt irgendwie ein Get geschrieben,

00:06:50.260 --> 00:06:52.020
irgendeine Klasse, Define, Get, bla bla bla.

00:06:52.460 --> 00:06:53.820
Und danach fange ich an mit Define.

00:06:54.320 --> 00:06:56.120
Und dann schlägt er mir als nächstes vor, Post zu definieren.

00:06:57.060 --> 00:06:58.280
Und zwar auch mit genau den richtigen

00:06:58.280 --> 00:07:00.080
Parametern und so. Das sind solche Sachen, das ist halt einfach,

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

00:07:02.380 --> 00:07:04.560
wow. Also ich bin wirklich beeindruckt

00:07:04.560 --> 00:07:06.300
davon, was das so macht. Also das ist so ein bisschen,

00:07:06.840 --> 00:07:08.180
man braucht keine Snippets mehr, ja,

00:07:08.180 --> 00:07:10.220
wenn man irgendwie Snippets-Sammlung hat, sondern man nimmt halt einfach

00:07:10.220 --> 00:07:12.340
dann das individualisierte Snippet

00:07:12.340 --> 00:07:13.880
und das ist echt mächtig, glaube ich.

00:07:14.500 --> 00:07:15.940
Also mir hat das schon echt Zeit gespart zwischendurch.

00:07:16.400 --> 00:07:18.980
Ich weiß gar nicht genau, auf welchem Modell ist das?

00:07:20.040 --> 00:07:20.440
GPT-3?

00:07:20.520 --> 00:07:21.800
Ja, das ist ein GPT-3.

00:07:22.920 --> 00:07:24.240
Ja, also da geht einiges.

00:07:24.360 --> 00:07:26.840
Also ich meine, das ist vielleicht auch noch ganz interessant.

00:07:27.120 --> 00:07:28.100
Das ist so ein kleiner Abschweif,

00:07:28.200 --> 00:07:29.860
aber vielleicht auch nicht so uninteressant.

00:07:31.340 --> 00:07:33.340
Ich meine, Text ist ja im Grunde deutlich...

00:07:33.340 --> 00:07:34.580
Also dachte man ja immer,

00:07:34.800 --> 00:07:35.880
Sprache ist halt schwierig,

00:07:36.080 --> 00:07:38.760
aber tatsächlich ist das irgendwie einfacher als andere Probleme.

00:07:40.760 --> 00:07:43.480
Und wisst ihr, wie diese Modelle trainiert werden?

00:07:45.060 --> 00:07:45.460
Nein.

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

00:07:51.320 --> 00:07:53.680
Der Begriff dafür nennt sich Self-Supervised Learning.

00:07:54.700 --> 00:08:00.620
Und zwar deswegen, weil man halt zum Beispiel auf Text relativ gut Modelle trainieren kann,

00:08:00.720 --> 00:08:03.160
ohne irgendwelche gelabelten Daten zu haben zu müssen.

00:08:03.160 --> 00:08:04.780
Was man ja normalerweise ist immer das Problem bei,

00:08:06.680 --> 00:08:12.980
wenn man so überwachte Modelle, also anführungsweise normale Machine Learning Modelle trainiert,

00:08:13.040 --> 00:08:14.720
dann braucht man halt Trainingsdaten.

00:08:15.040 --> 00:08:17.280
Und damit meint man üblicherweise halt Daten,

00:08:17.420 --> 00:08:19.480
wo man Labels

00:08:19.480 --> 00:08:21.060
angeschrieben hat, wie zum Beispiel jetzt, wenn man

00:08:21.060 --> 00:08:22.900
Bilder hat, so was ist ein Hund, das ist eine Katze

00:08:22.900 --> 00:08:24.540
und das ist, weiß ich nicht, irgendwas

00:08:24.540 --> 00:08:26.600
dazwischen oder so.

00:08:27.000 --> 00:08:29.640
Und bei Texten

00:08:29.640 --> 00:08:30.960
hat man das ja auch, da gibt es dann

00:08:30.960 --> 00:08:32.760
ein klassisches Problem wie Textkategorisierung.

00:08:32.920 --> 00:08:34.660
Da hast du halt einen Text und dann steht da zum Beispiel so diese

00:08:34.660 --> 00:08:36.880
Newsreuters-Artikel und da steht dran, das ist jetzt Sport

00:08:36.880 --> 00:08:38.640
oder das ist Politik oder das ist halt irgendwas anderes.

00:08:41.720 --> 00:08:42.840
Cool wäre ja so das Label wie

00:08:42.840 --> 00:08:43.980
will ich lesen, will ich nicht lesen?

00:08:45.040 --> 00:08:46.840
kann man auch alles machen. Spezifisch für dich, Dominik.

00:08:46.900 --> 00:08:49.000
Wenn du da Trainingsdaten hast, dann kannst du

00:08:49.000 --> 00:08:50.820
Modelle drauf trainieren, die dann auch wahrscheinlich halbwegs gut

00:08:50.820 --> 00:08:52.220
funktionieren sollten. Also das geht alles.

00:08:53.660 --> 00:08:55.040
Aber das Problem ist natürlich, dass

00:08:55.040 --> 00:08:56.980
für die meisten Probleme, die man so hat, hat man halt

00:08:56.980 --> 00:08:58.880
eben keine Trainingsdaten. Und das Erstellen von

00:08:58.880 --> 00:09:00.920
Trainingsdaten ist halt so aufwendig, dass sich das

00:09:00.920 --> 00:09:02.920
dann meistens nicht lohnt, das zu machen. Wie viel braucht man

00:09:02.920 --> 00:09:04.000
denn da? Ungefähr 100.000?

00:09:05.000 --> 00:09:06.700
Also kommt drauf an, wie gut es sein soll.

00:09:07.380 --> 00:09:08.520
Und dann entsprechend

00:09:08.520 --> 00:09:11.020
halt unter Umständen schon Millionen von Beispielen

00:09:11.020 --> 00:09:13.160
oder so. Und das ist dann halt doof, weil das ist einfach zu viel.

00:09:13.600 --> 00:09:15.220
Die meisten Leute haben so viele Beispiele gar nicht, ja.

00:09:15.440 --> 00:09:17.840
Ne, genau. Also einmal, du hast gar nicht genug

00:09:17.840 --> 00:09:19.940
Beispiele, um sie labeln zu können, dann musst du die erstmal besorgen,

00:09:20.000 --> 00:09:21.440
dann musst du es auch noch irgendwie labeln, dann hast du

00:09:21.440 --> 00:09:23.840
Fehler in den Labels, weil halt die Leute das

00:09:23.840 --> 00:09:25.760
nicht perfekt gemacht haben und dann musst du das irgendwie

00:09:25.760 --> 00:09:27.840
kontrollieren und dann schwuppdiwupp

00:09:27.840 --> 00:09:29.600
hast du irgendwie so ein Redaktionssystem und

00:09:29.600 --> 00:09:31.840
eine Technische Redaktion und

00:09:31.840 --> 00:09:33.820
dann Prozesse und keine Ahnung und

00:09:33.820 --> 00:09:35.740
Abstimmungen und das kostet ein Schweinegeld und

00:09:35.740 --> 00:09:37.080
das macht dann halt keiner so einfach so.

00:09:37.640 --> 00:09:39.200
Sondern nur, wenn man es halt wirklich, wirklich braucht.

00:09:40.440 --> 00:09:43.540
ja, aber man kann

00:09:43.540 --> 00:09:45.560
halt aus Text auch lernen,

00:09:45.720 --> 00:09:46.640
ohne diese ganzen Geschichten

00:09:46.640 --> 00:09:49.520
haben zu müssen. Also es gab

00:09:49.520 --> 00:09:51.480
ein Paper 2017, ist das glaube ich

00:09:51.480 --> 00:09:53.360
irgendwie, Attention is all you need, da

00:09:53.360 --> 00:09:55.340
wurde halt diese Transformer-Architektur

00:09:55.340 --> 00:09:57.040
eingeführt und

00:09:57.040 --> 00:09:59.440
diese

00:09:59.440 --> 00:10:01.100
Dinge funktionieren auf Sprache halt total super

00:10:01.100 --> 00:10:03.480
und die

00:10:03.480 --> 00:10:05.420
funktionieren so, dass man

00:10:05.420 --> 00:10:07.380
quasi Texte nimmt und lässt

00:10:07.380 --> 00:10:09.020
halt jetzt Wörter weg

00:10:09.020 --> 00:10:11.400
aus den Texten und lässt das Modell

00:10:11.400 --> 00:10:13.260
jetzt vorhersagen, okay, welches Wort gehört denn an die Stelle

00:10:13.260 --> 00:10:14.740
und

00:10:14.740 --> 00:10:17.060
dann

00:10:17.060 --> 00:10:20.060
bestraft man das, dann hat man halt

00:10:20.060 --> 00:10:22.080
Feedback, wenn das Modell jetzt ein anderes Wort

00:10:22.080 --> 00:10:23.880
als da stand vorher sagt, dann sagt man

00:10:23.880 --> 00:10:26.060
okay, das war jetzt falsch und dann kann man

00:10:26.060 --> 00:10:28.080
halt irgendwie ein Gradient

00:10:28.080 --> 00:10:30.040
bestimmen, in welche Richtung müssen sich die Gewichte ändern

00:10:30.040 --> 00:10:31.180
von dem Modell und dann

00:10:31.180 --> 00:10:33.580
propagiert man die halt zurück und dann

00:10:33.580 --> 00:10:35.860
ändert man das Modell ein bisschen in die Richtung,

00:10:35.980 --> 00:10:37.420
dass es das halt beim nächsten Mal besser macht.

00:10:37.980 --> 00:10:39.900
Und das macht man dann ganz oft und dann

00:10:39.900 --> 00:10:42.080
kann es halt aus einem

00:10:42.080 --> 00:10:44.040
Text, ohne dass man da irgendwelche Labels explizit

00:10:44.040 --> 00:10:46.220
für bräuchte oder so, Dinge lernen

00:10:46.220 --> 00:10:48.160
und zwar fast alles und das ist halt das Interessante.

00:10:48.340 --> 00:10:48.880
Das ist wirklich cool.

00:10:49.000 --> 00:10:51.880
Man kann das gesamte Internet nehmen und

00:10:51.880 --> 00:10:53.980
dann lernt das halt lustigerweise

00:10:53.980 --> 00:10:55.800
eben nicht nur irgendwie so

00:10:55.800 --> 00:10:57.340
stumpf, welches Wort

00:10:57.340 --> 00:10:59.880
die höchste Wahrscheinlichkeit hat, da zu stehen,

00:11:00.160 --> 00:11:01.900
sondern um das gut machen zu können,

00:11:02.060 --> 00:11:03.920
lernt das halt auch eine ganze Menge Konzepte

00:11:03.920 --> 00:11:05.840
und wie Dinge in Verhältnissen stehen und

00:11:05.840 --> 00:11:08.040
solche Sachen. Auch Kontext tatsächlich, das ist halt spannend.

00:11:08.220 --> 00:11:09.860
Also zum Beispiel, das Plugin

00:11:09.860 --> 00:11:12.020
schafft das halt auch, Kommentare

00:11:12.020 --> 00:11:14.000
richtig zu schreiben. Das heißt, ich fange mit einem Kommentar

00:11:14.000 --> 00:11:16.000
an, zwei Worte, und das macht einen relativ guten

00:11:16.000 --> 00:11:17.360
Vorschlag für, was da stehen sollte.

00:11:18.940 --> 00:11:19.860
Ja, genau.

00:11:20.080 --> 00:11:22.140
Das ist eine

00:11:22.140 --> 00:11:23.800
Geschichte, die man halt auch machen kann, dass man sagt, okay,

00:11:24.260 --> 00:11:25.880
das ist ein Text, der Rest ist halt Lücke, dann

00:11:25.880 --> 00:11:27.920
füll mal. Und dann kommen da auch

00:11:27.920 --> 00:11:29.180
schon ganz interessante Geschichten bei raus.

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

00:11:31.760 --> 00:11:33.600
anguckt, dann ist halt schon immer so, dass man

00:11:33.600 --> 00:11:35.660
irgendwann wird so leicht absurd oder

00:11:35.660 --> 00:11:37.780
sehr verdreht irgendwie und merkt

00:11:37.780 --> 00:11:39.800
so, okay, so ganz, schon so ein bisschen

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

00:11:42.020 --> 00:11:43.400
Die meandern auch so ein bisschen, oder?

00:11:43.980 --> 00:11:46.500
Wenn man halt so ein bisschen Gedächtnis so ein richtiges...

00:11:46.500 --> 00:11:48.740
Kann man es sehr schnell kaputt machen, dann kann es immer so...

00:11:48.740 --> 00:11:52.980
Ja, ich habe noch was dazu gelesen, was in eine andere Richtung geht.

00:11:53.240 --> 00:11:56.980
Dass es jetzt wohl eine große Anzahl inzwischen von wissenschaftlichen Veröffentlichungen gibt,

00:11:57.800 --> 00:12:02.380
denen man durch Analyse ansehen kann, dass eben nicht von einem Menschen geschrieben wurden,

00:12:02.460 --> 00:12:04.080
sondern von einem neuronalen Netzwerk.

00:12:04.840 --> 00:12:07.700
Und die Technik, die die da verwendet haben, die ist total witzig,

00:12:07.700 --> 00:12:16.700
Weil diese Netzwerke für so Paper-Generierung und für Text-Generierung generell, die sind, die werden wohl bestraft, wenn sie Plagiate erzeugen.

00:12:16.720 --> 00:12:17.460
Weil das willst du natürlich nicht.

00:12:17.560 --> 00:12:20.280
Du willst natürlich nicht ein Paper einreichen, was dann als Plagiate abrechtet.

00:12:20.540 --> 00:12:24.000
Und deshalb wählen die sehr viele Synonyme.

00:12:24.200 --> 00:12:25.400
Die sprechen sehr viel in Synonymen.

00:12:25.980 --> 00:12:31.380
Und auch eben so Fachbegriffe werden dann oft in Synonymen genommen.

00:12:31.380 --> 00:12:37.300
Das nette Beispiel, was ich erkenne, war eben, dass da die Paper über Big Data, die haben die ganze Zeit über Colossal Information gesprochen.

00:12:37.700 --> 00:12:40.320
was eben kein normaler Mensch

00:12:40.320 --> 00:12:42.380
schreiben würde und dann haben sie eben gesucht, wie oft

00:12:42.380 --> 00:12:44.020
dieses, dieser Begriff

00:12:44.020 --> 00:12:46.220
Colossal Information in Papern

00:12:46.220 --> 00:12:48.220
vorkommt und die dann eben genauer

00:12:48.220 --> 00:12:50.300
angesehen und die waren alle, hatten eben

00:12:50.300 --> 00:12:52.180
alle diese Anzeichen von erzeugten Papern

00:12:52.180 --> 00:12:54.220
und das ist so ein bisschen jetzt quasi

00:12:54.220 --> 00:12:56.220
die Kehrseite von Co-Pilot, dass die eben nicht

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

00:12:58.260 --> 00:13:00.200
Gutes einsetzen und nicht für

00:13:00.200 --> 00:13:02.120
Ja, da bist du ja schon

00:13:02.120 --> 00:13:03.360
positiv beizuschreiben.

00:13:04.440 --> 00:13:05.480
Ja, aber

00:13:05.480 --> 00:13:08.860
genau, was ich noch

00:13:08.860 --> 00:13:10.660
erwähnen wollte, war, genau, man kann

00:13:10.660 --> 00:13:12.520
jetzt halt sozusagen Modelle trainieren auf

00:13:12.520 --> 00:13:14.760
allen Texten, die es im Internet gibt und die lernen

00:13:14.760 --> 00:13:16.660
halt tatsächlich da auch Dinge dann raus

00:13:16.660 --> 00:13:18.720
und das ist natürlich total super und das geht bei Sprache

00:13:18.720 --> 00:13:19.800
vor allen Dingen deswegen, weil

00:13:19.800 --> 00:13:22.740
man halt eine endliche Anzahl

00:13:22.740 --> 00:13:25.020
von möglichen

00:13:25.020 --> 00:13:28.220
Füllern sozusagen für die Lücken hat.

00:13:28.220 --> 00:13:30.640
Was? Noam Chomsky würde dir widersprechen, Jochen.

00:13:31.060 --> 00:13:32.780
Jaja, gut, aber man kann

00:13:32.780 --> 00:13:34.700
sich da ja beschränken, kann ja sagen, okay, meine Sprache

00:13:34.700 --> 00:13:37.240
hat nur 20.000, 30.000

00:13:37.240 --> 00:13:39.360
Vokabeln

00:13:39.360 --> 00:13:40.760
und das war's. So größer ist

00:13:40.760 --> 00:13:41.920
mein Vocabulary einfach nicht.

00:13:42.380 --> 00:13:44.460
Wenn du immer nur ein Wort rausnimmst, ist natürlich klar.

00:13:44.520 --> 00:13:46.800
Und unter denen wird auch eins sein, das hinreichend

00:13:46.800 --> 00:13:48.520
nah dran ist. Und dann kannst du eben

00:13:48.520 --> 00:13:50.460
allen Worten eine Wahrscheinlichkeit zuweisen.

00:13:50.680 --> 00:13:51.600
Du kannst halt sagen, okay,

00:13:52.540 --> 00:13:54.660
das ist jetzt sehr, sehr unwahrscheinlich und das ist jetzt irgendwie,

00:13:54.660 --> 00:13:55.420
dass das geht.

00:13:56.540 --> 00:13:58.380
Es gibt ein bestimmtes Wort wie F,

00:13:58.480 --> 00:14:00.020
das fast überall hinpasst.

00:14:00.240 --> 00:14:00.580
Ja, klar.

00:14:03.860 --> 00:14:05.560
Aber das Modell ist dann halt auch,

00:14:05.820 --> 00:14:08.040
das Modell, das damit trainiert wird, passt dann aber nicht mehr

00:14:08.040 --> 00:14:09.800
überall hin, wenn du das als akzeptiert

00:14:09.800 --> 00:14:12.220
findest, dass das

00:14:12.220 --> 00:14:12.660
funktioniert.

00:14:16.440 --> 00:14:17.160
Jedenfalls, genau.

00:14:17.940 --> 00:14:19.460
Mit Sprache geht das total super.

00:14:20.240 --> 00:14:22.020
Und eben, Co-Pilot ist

00:14:22.020 --> 00:14:23.800
halt dann quasi auch eine Folge.

00:14:23.980 --> 00:14:25.920
Das Tolle ist, dass man jetzt Modelle,

00:14:25.920 --> 00:14:27.540
die da drauf trainiert sind, kann man jetzt mit

00:14:27.540 --> 00:14:29.920
ganz wenig Trainingsbeispielen auf das

00:14:29.920 --> 00:14:31.700
Problem sozusagen,

00:14:31.720 --> 00:14:33.880
das man wirklich hat, adaptieren.

00:14:34.100 --> 00:14:35.680
Also da braucht man dann nur noch ein paar

00:14:35.680 --> 00:14:37.720
Trainingsbeispiele, also nicht mehr viele.

00:14:37.980 --> 00:14:40.080
Ich glaube auch, er macht das tatsächlich anhand

00:14:40.080 --> 00:14:41.700
des Reposits, was du gerade aufhast.

00:14:41.980 --> 00:14:44.000
Kann er schon gucken und kann da schon dann die Completion

00:14:44.000 --> 00:14:45.920
zum Beispiel oder die Vorschläge anpassen

00:14:45.920 --> 00:14:47.600
auf das, was du da gerade machen willst. Und das ist schon echt

00:14:47.600 --> 00:14:49.900
wow. Naja, und das ist halt natürlich total

00:14:49.900 --> 00:14:51.720
toll, weil das dann

00:14:51.720 --> 00:14:53.740
halt bedeutet, dass du im Grunde dieses

00:14:53.740 --> 00:14:55.940
Trainingsproblem, Trainingsdatenproblem

00:14:55.940 --> 00:14:57.000
los wirst.

00:14:58.080 --> 00:15:00.040
Und ja, eine ganze

00:15:00.040 --> 00:15:01.560
Menge Anwendungsfälle plötzlich von

00:15:01.560 --> 00:15:03.540
ist zu aufwendig, unlösbar,

00:15:03.680 --> 00:15:05.040
lohnt sich nicht, in Richtung

00:15:05.040 --> 00:15:07.420
kann man schon mal probieren, wandern

00:15:07.420 --> 00:15:09.080
und dann ist es natürlich toll.

00:15:09.820 --> 00:15:11.580
Also da wird es hier eine Menge interessante

00:15:11.580 --> 00:15:13.400
Anwendungen geben. Also gerade für die ganzen

00:15:13.400 --> 00:15:15.480
FAUM-Programmierer unter uns, also das ganze Zeug

00:15:15.480 --> 00:15:17.560
drumherum, das geht halt einfach jetzt viel automatisierter.

00:15:17.980 --> 00:15:19.220
Hatte ich schon gesagt, muss man immer noch selber machen.

00:15:19.220 --> 00:15:21.120
Ja, ich bin dagegen, das ist schlecht für die

00:15:21.120 --> 00:15:23.020
Auftragsprogrammierer.

00:15:23.880 --> 00:15:25.580
Finde ich nicht gut. Ja, das kann schon

00:15:25.580 --> 00:15:26.620
sein. Ja.

00:15:29.180 --> 00:15:29.540
Aber

00:15:29.540 --> 00:15:31.380
genau, das Problem ist aber

00:15:31.380 --> 00:15:33.260
jetzt, dass man das nicht machen kann

00:15:33.260 --> 00:15:35.200
für, also was halt, also man würde,

00:15:35.460 --> 00:15:37.180
wäre sehr viel weiter, wenn man das

00:15:37.180 --> 00:15:39.200
jetzt auch für zum Beispiel Bilddaten machen könnte.

00:15:40.080 --> 00:15:41.280
Also und tatsächlich ist

00:15:41.280 --> 00:15:42.520
es wohl so, dass es da

00:15:42.520 --> 00:15:47.340
gibt es auch inzwischen Forschung zu, das ist halt

00:15:47.340 --> 00:15:49.220
tatsächlich der Weg, also man hat sich ja das oft lange

00:15:49.220 --> 00:15:51.200
oder ich erinnere mich noch dran, dass es mal völlig

00:15:51.200 --> 00:15:53.260
unklar war, wie das eigentlich funktioniert.

00:15:53.560 --> 00:15:54.760
Wie lernen Kinder eigentlich

00:15:54.760 --> 00:15:57.260
sozusagen

00:15:57.260 --> 00:15:58.580
so schnell Dinge,

00:15:59.180 --> 00:16:01.180
man versteht es nicht, sie sehen eigentlich

00:16:01.180 --> 00:16:03.260
zu wenig Trainingsbeispiele für das, was sie da

00:16:03.260 --> 00:16:04.400
lernen. Und

00:16:04.400 --> 00:16:07.380
tatsächlich lernen sie ja auch

00:16:07.380 --> 00:16:09.280
sowas, was einem die Forschung

00:16:09.280 --> 00:16:11.080
sagt, manchmal Schwierigkeiten hat,

00:16:11.180 --> 00:16:12.880
das einfach so zu akzeptieren. Aber

00:16:12.880 --> 00:16:15.260
die sagt halt, ja, also das meiste, was

00:16:15.260 --> 00:16:17.100
Menschen so lernen, lernen sie halt so in den ersten

00:16:17.100 --> 00:16:18.940
neun Monaten. Und alles, was danach kommt, ist halt so,

00:16:19.060 --> 00:16:20.840
naja, Gott, also ich meine so Details.

00:16:21.520 --> 00:16:23.200
Also die wesentlichen Dinge

00:16:23.200 --> 00:16:25.200
sind bis dahin gelernt. Dann fragt man sich, wie machen

00:16:25.200 --> 00:16:27.080
die das denn? Ich meine, Kinder in dem Alter verstehen

00:16:27.080 --> 00:16:29.060
einfach gar nichts. Die

00:16:29.060 --> 00:16:31.000
kennen auch keine Worte für nichts. Wieso können die denn

00:16:31.000 --> 00:16:33.020
so viel lernen? Wie soll das gehen? Das ist

00:16:33.020 --> 00:16:34.740
irgendwie alles seltsam. Und

00:16:34.740 --> 00:16:36.960
tatsächlich ist es wohl so, dass die halt auch

00:16:36.960 --> 00:16:38.980
so eine Art self-supervised learning

00:16:38.980 --> 00:16:41.020
machen und quasi genau

00:16:41.020 --> 00:16:42.240
das gleiche Prinzip irgendwie,

00:16:42.940 --> 00:16:44.520
also sie sehen halt was

00:16:44.520 --> 00:16:46.860
und Dinge passieren und dann

00:16:46.860 --> 00:16:48.960
betrachten sie das sozusagen als eine Art

00:16:48.960 --> 00:16:50.780
Lückentext und füllen das dann halt und das funktioniert.

00:16:51.420 --> 00:16:52.780
Genau, das ist das Ego, was das dann macht.

00:16:53.120 --> 00:16:55.040
Naja, keine Ahnung. Ja, aber das zieht

00:16:55.040 --> 00:16:57.040
das dann irgendwo aus dem Äther, irgendwelche Formationen

00:16:57.040 --> 00:16:58.980
schafft das dann dazwischen und deswegen hast du ja auch so,

00:16:59.660 --> 00:17:00.840
weiß nicht, ob ihr das kennt, wenn ihr irgendwo

00:17:00.840 --> 00:17:02.940
müde seid oder sowas, dann werden bestimmte Sachen ja auch

00:17:02.940 --> 00:17:04.880
einfach ersetzt. Der Kopf macht das ja sehr gerne,

00:17:05.300 --> 00:17:06.980
dass er bestimmte Flecken, die nicht so

00:17:06.980 --> 00:17:08.640
ganz klar sind, dann mit Sachen überschreibt.

00:17:09.180 --> 00:17:10.620
Einige Leute, die haben dann auch

00:17:10.620 --> 00:17:12.760
innere Stimme, die dann auf einmal selbst vervollständigt, die

00:17:12.760 --> 00:17:14.860
nur so halb gehört haben. Das kannst du auch

00:17:14.860 --> 00:17:16.880
mit optischen Informationen machen oder mit

00:17:16.880 --> 00:17:18.960
anderen optischen Signalen.

00:17:19.040 --> 00:17:20.880
Und das ist halt super spannend tatsächlich. Und wenn das

00:17:20.880 --> 00:17:22.840
halt Self-Supervised Learning ist, dann ist ja auch

00:17:22.840 --> 00:17:24.760
klar, dann hast du so ein Lückenbild. Das ist

00:17:24.760 --> 00:17:26.680
so ein bisschen so, du hast ein Foto, da fehlt

00:17:26.680 --> 00:17:28.340
ein Teil und dann wird das automatisch ersetzt.

00:17:28.700 --> 00:17:30.260
Das ist spannend. Wenn die KI das kann, dann kann man quasi

00:17:30.260 --> 00:17:32.640
machst du ein Hochzeitsbild von dir, dann kannst du irgendwie deinen Partner

00:17:32.640 --> 00:17:34.440
rausschneiden, dann kannst du den idealen Partner auf einmal sehen.

00:17:35.960 --> 00:17:36.520
Ah ja, und

00:17:36.520 --> 00:17:38.940
so ist also dieses Python-Import-System

00:17:38.940 --> 00:17:39.860
entstanden.

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

00:17:41.820 --> 00:17:42.920
Willst du jetzt zum Topic zurück?

00:17:43.980 --> 00:17:46.700
Nein, nein. Nur ganz kurz, also das, was halt

00:17:46.700 --> 00:17:48.460
momentan nicht geht, was man nicht hinkriegt,

00:17:48.580 --> 00:17:50.280
was halt total toll wäre, wenn man es irgendwie hinkriegen würde,

00:17:50.360 --> 00:17:51.640
also vielleicht hat ja irgendjemand eine Idee,

00:17:52.140 --> 00:17:54.600
das große ungelöste Problem an der Stelle ist halt,

00:17:54.920 --> 00:17:56.260
wenn du jetzt ein Bild aus einem,

00:17:56.600 --> 00:17:58.220
ein Teil aus einem Bild rausnimmst und sagst so,

00:17:58.280 --> 00:18:00.380
das ist jetzt leer. Also einmal

00:18:00.380 --> 00:18:02.380
man kann halt irgendwie die

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

00:18:04.520 --> 00:18:05.600
nicht aufzählen, nicht so richtig.

00:18:06.320 --> 00:18:07.300
Und dann ist es so,

00:18:07.640 --> 00:18:10.420
selbst wenn man sich irgendwie beschränkt,

00:18:10.860 --> 00:18:12.520
weiß man nicht, so jetzt hat man

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

00:18:14.400 --> 00:18:16.480
mit dem Bild, das man eigentlich an der

00:18:16.480 --> 00:18:18.380
Stelle gerne hätte. Welche Wahrscheinlichkeit weist man

00:18:18.380 --> 00:18:20.220
hinzu und wie ist der Gradient in welche Richtung?

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

00:18:22.460 --> 00:18:24.260
hast, in dem das drumherum gestellt werden soll,

00:18:24.740 --> 00:18:26.300
der halt selber ein Objekt ist,

00:18:26.340 --> 00:18:27.720
das viele verschiedene Informationen beinhaltet,

00:18:27.800 --> 00:18:31.600
dann ist es besser, diese Menge an abzählbaren Elementen zu bilden

00:18:31.600 --> 00:18:33.500
und das entsprechend herauszusuchen mit der höchsten Wahrscheinlichkeit.

00:18:34.360 --> 00:18:36.620
Das heißt also, ohne Kontext ist das wahrscheinlich nicht so einfach möglich,

00:18:36.720 --> 00:18:38.380
dass du einfach so ein Bild machst, das dann gut trifft.

00:18:38.560 --> 00:18:40.340
Aber wenn du Informationen über den Kontext hast,

00:18:40.380 --> 00:18:41.800
in dem du dieses Bild ersetzen möchtest.

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

00:18:44.480 --> 00:18:46.320
Also du kannst ja durchaus ein Modell trainieren,

00:18:46.420 --> 00:18:47.840
was dann irgendwas vorhersagt an der Stelle.

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

00:18:52.880 --> 00:18:55.360
Da hat das jetzt die Wahrscheinlichkeit 0,376

00:18:55.360 --> 00:18:57.080
oder 0,652.

00:18:57.580 --> 00:18:58.860
Und das macht ja einen Unterschied fürs Training.

00:18:59.020 --> 00:19:00.860
Aber es ist halt völlig unklar, wie man das,

00:19:02.200 --> 00:19:03.440
wie man da die Wahrscheinlichkeit

00:19:03.440 --> 00:19:04.000
ausrechnen soll.

00:19:04.760 --> 00:19:06.060
Ja, vielleicht braucht man dafür echt einen Kontext,

00:19:06.300 --> 00:19:08.840
der das eingesetzt werden soll. Das glaube ich gar nicht so.

00:19:09.520 --> 00:19:11.260
Ja, also das ist auf jeden Fall, wenn da jemand eine Idee hat,

00:19:11.320 --> 00:19:11.620
voll gut.

00:19:12.600 --> 00:19:14.760
Aber das war jetzt auch gerade wieder so ein Ding,

00:19:14.820 --> 00:19:16.360
was halt passiert, wenn man halt den Kontext nicht hat,

00:19:16.420 --> 00:19:19.480
dann passiert sowas wie ein Relative Import Beyond Top Level Package

00:19:19.480 --> 00:19:19.880
oder so.

00:19:20.220 --> 00:19:22.620
Oh, das war so ein Syntaxfehler quasi.

00:19:22.720 --> 00:19:27.080
Ich sehe schon, es gibt eine gewisse Abschüssigkeit in eine bestimmte Richtung.

00:19:27.220 --> 00:19:28.820
Ja, Importsystem ist auch voll interessant.

00:19:29.580 --> 00:19:29.840
Na gut.

00:19:31.200 --> 00:19:33.560
Ja, Entschuldigung, es war gerade ein Versuch, da so ein bisschen hinzukommen,

00:19:33.600 --> 00:19:35.740
weil wir wollten ja über das Importsystem tatsächlich reden

00:19:35.740 --> 00:19:37.520
und wie man das in Python macht.

00:19:38.200 --> 00:19:40.420
Und ich glaube, als Basis irgendwie das so ein bisschen zu verstehen.

00:19:40.520 --> 00:19:42.760
Es gibt einen super tollen Blog, den ich auch erst letztens entdeckt habe,

00:19:42.760 --> 00:19:46.960
der 10.000 Meters heißt, der irgendwie auf Hacker News nochmal gefeatured worden ist.

00:19:47.180 --> 00:19:51.380
Und da hat ein Mensch namens Viktor Skvorstov, wenn ich ihn richtig ausspreche,

00:19:51.540 --> 00:19:53.640
einen Artikel geschrieben, wie das

00:19:53.640 --> 00:19:55.260
Preis- und Importsystem funktioniert.

00:19:56.580 --> 00:19:57.560
Und das hat er so ein bisschen erklärt.

00:19:57.640 --> 00:19:58.800
Das ist sehr spannend zu lesen.

00:19:59.700 --> 00:20:00.700
Fangen wir auf jeden Fall in die Shownotes.

00:20:01.560 --> 00:20:03.020
Und ja, wie funktioniert denn das eigentlich?

00:20:03.600 --> 00:20:04.940
Was ist denn das Preis- und Importsystem?

00:20:05.000 --> 00:20:06.960
Ja, ich habe diesen Artikel auf Hacker News gesehen

00:20:06.960 --> 00:20:08.160
und auch die Diskussion dann so ein bisschen.

00:20:08.180 --> 00:20:09.200
bisschen angeguckt und

00:20:09.200 --> 00:20:12.260
da ist mir aufgefallen,

00:20:12.380 --> 00:20:13.960
dass das doch tatsächlich erstaunlich viel

00:20:13.960 --> 00:20:16.120
komplizierter ist, als man

00:20:16.120 --> 00:20:17.700
das so denkt oder als man das so im Kopf hat.

00:20:19.820 --> 00:20:20.180
Was

00:20:20.180 --> 00:20:22.040
mir gar nicht so aufgefallen war,

00:20:22.320 --> 00:20:24.160
weil ich offenbar nicht alle

00:20:24.160 --> 00:20:26.000
Features benutze, die es da so gibt.

00:20:26.440 --> 00:20:28.020
Vielleicht ganz kurz, bevor wir darauf einsteigen,

00:20:28.120 --> 00:20:29.980
was ist denn überhaupt das Problem damit? Könnte das sein?

00:20:30.080 --> 00:20:32.140
Wir haben irgendwie so eine Story gehört, dass das mal lange dauern kann

00:20:32.140 --> 00:20:34.120
und doof sein kann. Worum geht's denn

00:20:34.120 --> 00:20:35.880
da überhaupt? Und warum braucht

00:20:35.880 --> 00:20:38.060
Python ein Import-System überhaupt? Das ist ja auch eine spannende Sache.

00:20:38.180 --> 00:20:39.780
Weil in anderen Sprachen ist das ja anders gelöst.

00:20:40.460 --> 00:20:42.060
Und zum Teil besser und zum Teil schlechter.

00:20:43.760 --> 00:20:43.900
Ja.

00:20:44.920 --> 00:20:45.980
Wer will anfangen?

00:20:46.700 --> 00:20:48.300
Also ich würde sagen, ja, vielleicht kann man

00:20:48.300 --> 00:20:50.180
genauso anfangen wie der Artikel. Was passiert denn,

00:20:50.260 --> 00:20:51.100
wenn man sagt Import M?

00:20:52.420 --> 00:20:53.740
Warum sagt man das denn überhaupt, Jörg?

00:20:54.480 --> 00:20:55.580
Warum sagt man Import M?

00:20:56.460 --> 00:20:58.100
Ja, es gibt natürlich

00:20:58.100 --> 00:21:00.100
Build-ins, aber nicht alles sind Build-ins.

00:21:00.100 --> 00:21:01.840
Und manchmal möchte man halt irgendwo

00:21:01.840 --> 00:21:03.980
Funktionen oder Klassen oder sonst irgendwas

00:21:03.980 --> 00:21:04.460
verwenden.

00:21:06.360 --> 00:21:08.000
Oder man möchte einfach seinen Code trennen und nicht alles

00:21:08.000 --> 00:21:09.920
eine einzige Feier. Also man möchte halt irgendwas

00:21:09.920 --> 00:21:11.760
verwenden, was nicht in der aktuellen Datei definiert ist.

00:21:13.180 --> 00:21:14.200
Genau. Und jetzt könnte

00:21:14.200 --> 00:21:15.900
ich verschiedene Dinge, ich könnte mir

00:21:15.900 --> 00:21:18.220
die Datei nehmen und sie e-ballen.

00:21:18.920 --> 00:21:19.620
Könnte ich machen.

00:21:20.480 --> 00:21:20.600
Ja.

00:21:21.920 --> 00:21:22.320
Wäre

00:21:22.320 --> 00:21:24.720
auch möglich, oder?

00:21:25.500 --> 00:21:27.620
Hat auch einen ähnlichen Effekt irgendwie.

00:21:27.840 --> 00:21:29.760
Ja, genau. Aber das

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

00:21:31.580 --> 00:21:33.260
zum Beispiel da drin halt,

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

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

00:21:38.000 --> 00:21:38.960
Ja, und dann

00:21:38.960 --> 00:21:41.660
wenn man so Counter-Variablen hat oder so,

00:21:41.740 --> 00:21:42.900
die sind dann wahrscheinlich hinterher anders.

00:21:44.000 --> 00:21:44.960
Vielleicht, ja, vielleicht.

00:21:45.360 --> 00:21:47.740
Ja, oder auch Namen, die einfach gängig

00:21:47.740 --> 00:21:49.820
sind, werden vielleicht eventuell überschrieben.

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

00:21:51.700 --> 00:21:53.260
irgendwie sowas, das macht ja so ein

00:21:53.260 --> 00:21:55.620
Namespace wieder. Ja, genau, das müsstest

00:21:55.620 --> 00:21:57.580
du dir dann, also wenn du einfach die Datei lädst

00:21:57.580 --> 00:21:59.480
und ausführst, also

00:21:59.480 --> 00:22:01.180
IWR drauf machst, dann

00:22:01.180 --> 00:22:03.780
ja, drückst du halt erstmal alles in die Hand.

00:22:04.420 --> 00:22:05.700
Und da wäre dann, hätte man

00:22:05.700 --> 00:22:07.640
dann auch wieder das Problem mit dieser Rekursion, die müssen wir auch irgendwie

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

00:22:09.560 --> 00:22:11.360
derweil

00:22:11.360 --> 00:22:13.340
importieren und e-wählen und

00:22:13.340 --> 00:22:15.580
vielleicht hast du ja sogar das Problem, dass

00:22:15.580 --> 00:22:17.140
du es zyklisch machst.

00:22:17.280 --> 00:22:18.640
Aber das Problem haben wir in Python auch.

00:22:19.100 --> 00:22:20.940
Das Problem haben wir in Python auch, ja, aber

00:22:20.940 --> 00:22:23.400
muss man mal überlegen, wie das das macht.

00:22:23.800 --> 00:22:25.800
Aber in anderen Sprachen,

00:22:26.440 --> 00:22:27.580
um da noch kurz drauf anzugehen,

00:22:27.640 --> 00:22:29.680
braucht man es ja, macht man es ja nicht.

00:22:30.320 --> 00:22:31.660
In Java oder in C++

00:22:31.660 --> 00:22:33.620
macht man es ja nicht, dass man einfach

00:22:33.620 --> 00:22:35.180
andere Dateien da reinkopiert,

00:22:36.200 --> 00:22:37.620
weil da ja die

00:22:37.620 --> 00:22:39.480
Organisation anders ist. Da braucht man ja quasi

00:22:39.480 --> 00:22:41.400
keine Objekte in der Hand, sondern nur

00:22:41.400 --> 00:22:43.560
einen Verweis auf die entsprechenden Stellen

00:22:43.560 --> 00:22:45.600
im Code. Das heißt, bei denen

00:22:45.600 --> 00:22:47.640
funktioniert das Import-System halt,

00:22:47.880 --> 00:22:49.580
weil das während des Kompilierens passiert,

00:22:50.960 --> 00:22:51.640
deutlich anders

00:22:51.640 --> 00:22:52.680
als in Python.

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

00:22:55.800 --> 00:22:57.640
Also wenn ich in

00:22:57.640 --> 00:22:58.560
C sage include,

00:22:59.220 --> 00:23:01.500
das wäre das eine Datei.

00:23:02.040 --> 00:23:03.560
Genau, aber wenn du zum Beispiel in C

00:23:03.560 --> 00:23:05.660
inkludierst, die ja normalerweise

00:23:05.660 --> 00:23:07.700
nur .h-Dateien. Und da sind ja

00:23:07.700 --> 00:23:10.120
keine Definitionen

00:23:10.120 --> 00:23:11.920
drin. Da sind ja nur Deklarationen drin.

00:23:12.200 --> 00:23:13.460
Da steht nur drin,

00:23:13.540 --> 00:23:15.780
es gibt etwas, was heißt so und so.

00:23:16.160 --> 00:23:17.680
Und das ist das Einzige, was du an der Stelle

00:23:17.680 --> 00:23:19.880
da reinkriegst. Das Zusammenführen,

00:23:20.000 --> 00:23:21.720
was dann tatsächlich der Code ist oder was

00:23:21.720 --> 00:23:23.880
diese Werte sind, das passiert erst später im

00:23:23.880 --> 00:23:25.760
Link-Vorgang, wenn du schon alles

00:23:25.760 --> 00:23:27.860
kompiliert hast. Und diese Phasen

00:23:27.860 --> 00:23:29.640
gibt es bei Python ja einfach überhaupt nicht.

00:23:30.220 --> 00:23:31.880
Bei Python gibt es ja nur die Phase Ausführen.

00:23:32.460 --> 00:23:33.840
Und zu dem Zeitpunkt brauchst du es

00:23:33.840 --> 00:23:34.960
dann jetzt. Und

00:23:34.960 --> 00:23:36.740
was viele Leute vergessen,

00:23:37.340 --> 00:23:39.560
wenn du define schreibst, wenn du eine Funktion definierst,

00:23:40.540 --> 00:23:41.380
wenn du eine

00:23:41.380 --> 00:23:43.320
Funktion erstellst, dann ist

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

00:23:45.400 --> 00:23:47.260
an Python und der heißt,

00:23:47.380 --> 00:23:49.360
merkt ihr mal unter dem Namen, keine Ahnung,

00:23:49.480 --> 00:23:51.520
fun, ein Code-Objekt,

00:23:51.600 --> 00:23:53.200
was folgende Eigenschaften hat.

00:23:53.260 --> 00:23:55.180
Es ist callable und dieser callable hat

00:23:55.180 --> 00:23:57.320
folgende Parameter und dann steht da Code

00:23:57.320 --> 00:23:59.260
drin und so weiter und so fort. Und auch bei

00:23:59.260 --> 00:24:00.420
class, wenn du class

00:24:00.420 --> 00:24:03.240
als Schlüsselwort, wird ja erstmal alles

00:24:03.240 --> 00:24:05.380
ausgeführt, was da drin ist. Das heißt, du kannst da prinzipiell

00:24:05.380 --> 00:24:06.420
Code drin haben, der

00:24:06.420 --> 00:24:09.160
Sachen tut, was ja auch an vielen Stellen

00:24:09.160 --> 00:24:11.200
sehr wichtig ist, was du aber in anderen

00:24:11.200 --> 00:24:12.520
Systemen nicht hast.

00:24:13.260 --> 00:24:15.660
In der Java und in der C++ hast du

00:24:15.660 --> 00:24:16.880
das nicht, das wird nicht ausgeführt.

00:24:17.640 --> 00:24:19.440
Es wird zum Teil ausgeführt bei C,

00:24:19.520 --> 00:24:21.240
weil du da diesen komischen Pre-Processor hast

00:24:21.240 --> 00:24:23.000
und weil der auch so

00:24:23.000 --> 00:24:25.120
Constant-Optimizations

00:24:25.120 --> 00:24:27.680
versucht schon mal zu machen, aber generell

00:24:27.680 --> 00:24:29.320
wird C-Code

00:24:29.320 --> 00:24:30.920
erst ausgeführt, wenn du das Programm startest.

00:24:31.060 --> 00:24:31.780
Das ist bei Python

00:24:31.780 --> 00:24:35.180
Schritt des Kompilierens gibt es ja bei Python nicht.

00:24:35.220 --> 00:24:37.000
Der ist ja da so ein bisschen innen drin.

00:24:37.620 --> 00:24:38.900
Das heißt, du kannst auch mit Import

00:24:38.900 --> 00:24:39.960
Sachen ausführen.

00:24:42.640 --> 00:24:43.040
Was

00:24:43.040 --> 00:24:44.580
manchmal komisch ist und manchmal gewünscht

00:24:44.580 --> 00:24:46.420
und manchmal überraschend.

00:24:47.340 --> 00:24:48.760
Ja, also das ist manchmal

00:24:48.760 --> 00:24:50.900
tatsächlich, wenn man Sachen importiert,

00:24:50.960 --> 00:24:52.740
dass dann halt alles in dem Modul ausgeführt wird,

00:24:52.840 --> 00:24:54.680
was auf dem Top-Level ist. Das ist halt schon

00:24:54.680 --> 00:24:57.120
manchmal eher überraschend.

00:24:58.480 --> 00:24:59.140
Warum passiert

00:24:59.140 --> 00:25:00.940
das denn auch? Warum wird das dann ausgeführt? Also wenn man jetzt

00:25:00.940 --> 00:25:02.100
ein Import schreibt, Import M

00:25:02.100 --> 00:25:04.460
von irgendwo, was dann...

00:25:04.460 --> 00:25:06.880
Einfach nur Import M, also wirklich nur

00:25:06.880 --> 00:25:08.520
diese Zeile Import M. Was passiert dann?

00:25:09.220 --> 00:25:10.920
Ja, das ist eine gute Frage.

00:25:11.440 --> 00:25:12.900
Und auf den ersten Blick ist es

00:25:12.900 --> 00:25:14.700
finde ich so ein bisschen offensichtlich, was da passiert.

00:25:14.840 --> 00:25:16.880
Und auf den zweiten Blick ist es dann tatsächlich doch nicht so offensichtlich,

00:25:17.000 --> 00:25:17.800
wie eben dieser Artikel,

00:25:18.620 --> 00:25:20.900
glaube ich, uns allen demonstriert hat.

00:25:21.780 --> 00:25:23.160
Also für mich bedeutet Import M

00:25:23.160 --> 00:25:25.220
suche eine Datei,

00:25:25.320 --> 00:25:26.480
die M.py heißt

00:25:26.480 --> 00:25:28.940
und gib mir den

00:25:28.940 --> 00:25:30.820
Inhalt davon als Modul. Oh, das wäre aber ein Skript

00:25:30.820 --> 00:25:32.620
und man könnte auch ein Modul laden,

00:25:32.680 --> 00:25:34.180
was halt, wenn ein Modul heißt, das M heißt,

00:25:34.580 --> 00:25:36.000
das in einem Verzeichnis ist oder sowas.

00:25:36.280 --> 00:25:36.940
Oder was ist ein Modul?

00:25:36.960 --> 00:25:37.740
Nee, das wäre dann wieder was anderes.

00:25:37.920 --> 00:25:40.740
Ja, aber ein Verzeichnis ist ja auch nur so eine Art Datei.

00:25:41.200 --> 00:25:44.820
Ein Verzeichnis ist ja auch nur ein Verweis auf die InitPy.

00:25:44.960 --> 00:25:46.740
Also es gibt Module und Packages.

00:25:46.820 --> 00:25:47.900
Und was ist denn überhaupt der Unterschied?

00:25:48.000 --> 00:25:49.680
Was ist ein Skript, was ein Modul, was ein Package?

00:25:51.000 --> 00:25:52.400
Ja, das ist schwer zu sagen.

00:25:52.660 --> 00:25:53.540
Ich finde es schwer zu sagen,

00:25:53.680 --> 00:25:56.460
weil für mich dieser Unterschied wirklich minimal ist.

00:25:56.460 --> 00:25:59.480
Das eine ist halt eine Datei und das andere ist ein Verzeichnis.

00:25:59.600 --> 00:26:01.640
aber das Verzeichnis selber hat ja

00:26:01.640 --> 00:26:03.520
keinen Inhalt und deshalb tut man so, als ob

00:26:03.520 --> 00:26:05.680
die Init-Pi, die da drin ist, dass der Inhalt

00:26:05.680 --> 00:26:06.740
dieses Verzeichnisses ist.

00:26:08.800 --> 00:26:09.740
Genau, in der Init-Pi

00:26:09.740 --> 00:26:11.560
kann man auch sowas wie All dann definieren, das heißt, wenn man zum Beispiel

00:26:11.560 --> 00:26:13.520
sowas wie Import-Aspects, das kannst du auch

00:26:13.520 --> 00:26:15.260
in einer einzelnen Datei machen. Kannst du überall definieren.

00:26:15.940 --> 00:26:16.320
Ja, okay.

00:26:17.380 --> 00:26:19.120
Kannst du auch Slots definieren, das ist auch,

00:26:19.340 --> 00:26:21.120
kannst du auch überall machen. Ein Slot?

00:26:21.740 --> 00:26:23.620
Ja, das sind solche Sachen,

00:26:23.720 --> 00:26:25.420
die beim Import mitgebracht werden sollen.

00:26:29.240 --> 00:26:31.520
Genauso wie all. Wenn du all definierst

00:26:31.520 --> 00:26:33.480
und dann machst du from m import Stern, dann kriegst du alles das,

00:26:33.480 --> 00:26:35.400
was in all drin steht. Also unterstrich, unterstrich,

00:26:35.460 --> 00:26:37.480
all, unterstrich, unterstrich, um es jetzt mal hier korrekt

00:26:37.480 --> 00:26:39.980
zu sagen.

00:26:40.300 --> 00:26:41.120
Dann, dann, all, dann, dann.

00:26:41.280 --> 00:26:43.620
Das ist ein sehr guter Mechanismus, den sieht man sehr selten,

00:26:43.780 --> 00:26:45.620
weil import Stern

00:26:45.620 --> 00:26:46.400
ja so

00:26:46.400 --> 00:26:49.180
verpönt ist. So gerne gesehen wird.

00:26:49.520 --> 00:26:50.080
Es riecht.

00:26:50.380 --> 00:26:53.560
Das hatten wir schon in der ersten Vorlesung quasi

00:26:53.560 --> 00:26:55.360
in Informatik 1 hat uns unser Professor

00:26:55.360 --> 00:26:56.800
schon gesagt, ja, man kann using

00:26:56.800 --> 00:26:58.400
namespace standard nehmen.

00:26:59.240 --> 00:27:12.120
Und dann kann man mal gucken, wie viele Symbole da importiert werden und es waren irgendwie 13.000 oder sowas. Und das kannst du in Python natürlich auch machen, kannst auch from Stern import Stern probieren, kriegst halt auch 100.000 Sachen rein.

00:27:14.480 --> 00:27:15.780
Import Stern habe ich noch gar nicht probiert.

00:27:16.220 --> 00:27:17.860
Nee, nee, From Stern, Import Stern geht nicht.

00:27:17.980 --> 00:27:20.620
Aber so quasi, wenn du es dir vorstellst.

00:27:21.060 --> 00:27:24.100
Import Stern heißt halt, hol alles aus diesem Modul oder aus dem Package

00:27:24.100 --> 00:27:25.420
und gib es mir.

00:27:26.020 --> 00:27:28.960
Und meistens weiß man ja gar nicht ganz genau, was da drin ist.

00:27:29.060 --> 00:27:30.560
Meistens weiß man auch nicht, wie viel da drin ist.

00:27:31.640 --> 00:27:34.900
Und ganz oft sind da ja dann auch lokale Sachen drin,

00:27:34.940 --> 00:27:36.140
die man eigentlich gar nicht haben möchte.

00:27:36.140 --> 00:27:39.880
Oder Imports, die dieses Modul macht,

00:27:39.940 --> 00:27:42.480
die hast du dann auf einmal auch selber importiert.

00:27:43.020 --> 00:27:43.720
Subdependencies quasi.

00:27:44.080 --> 00:27:49.040
Genau, also wenn du in der m.py, so wie wir es jetzt eben drin hatten,

00:27:49.660 --> 00:27:54.220
wenn du da import x machst und dann machst du from m import Stern,

00:27:54.340 --> 00:27:59.120
hast du auch x importiert, weil das halt in dem Modul m dann schon drin ist.

00:27:59.200 --> 00:28:01.300
Und das ist genau der Grund, warum man dieses Stern nicht machen soll,

00:28:01.380 --> 00:28:03.720
weil man nämlich nicht weiß, was da drin ist und man halt dann alle Sachen,

00:28:03.720 --> 00:28:06.800
die es schon gab, bei einem Lokal irgendwo überschreiben würde.

00:28:06.880 --> 00:28:12.260
Und wenn mehrere Module oder Pakete dasselbe Namen definieren für irgendwas,

00:28:12.360 --> 00:28:14.160
was ja durchaus mal vorkommen kann, dann weiß man nicht

00:28:14.160 --> 00:28:16.520
mehr genau, was unter dem Namen jeweils Identität ist.

00:28:16.540 --> 00:28:18.100
Aber jetzt müssen wir ja erstmal klären, was Import

00:28:18.100 --> 00:28:20.140
überhaupt macht. Wir sprechen jetzt schon die ganze

00:28:20.140 --> 00:28:21.340
Zeit über, aber wir wissen es immer noch nicht.

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

00:28:25.000 --> 00:28:26.340
Ja, also ich glaube, das eine ist eine Datei

00:28:26.340 --> 00:28:28.240
und das andere ist ein Verzeichnis.

00:28:29.060 --> 00:28:30.760
Ja, aber ich glaube,

00:28:30.880 --> 00:28:31.420
es ist auch irgendwie,

00:28:32.260 --> 00:28:34.480
ich glaube, der entscheidende

00:28:34.480 --> 00:28:36.440
Unterschied ist, dass irgendwie ein Paket Submodule

00:28:36.440 --> 00:28:38.500
haben kann und ein Modul nicht.

00:28:39.600 --> 00:28:40.000
Also genau,

00:28:40.380 --> 00:28:42.340
ich habe eine Definition gefunden bei

00:28:42.340 --> 00:28:43.920
der irgendwo sagt hat dann,

00:28:44.000 --> 00:28:46.120
if a module name has no dots, it's not

00:28:46.120 --> 00:28:47.540
considered to be part of a package.

00:28:48.820 --> 00:28:48.980
Aha.

00:28:50.720 --> 00:28:51.960
Ja, okay.

00:28:52.000 --> 00:28:52.340
Mag sein.

00:28:52.500 --> 00:28:56.020
Also ein Paket ist halt quasi eine Sammlung von

00:28:56.020 --> 00:28:56.980
Modulen oder sowas.

00:28:58.160 --> 00:28:58.700
Okay, gut.

00:29:00.380 --> 00:29:01.500
Da gab es auch eine tolle Antwort drin.

00:29:01.620 --> 00:29:03.860
Relative imports for the billions times oder sowas.

00:29:03.860 --> 00:29:05.920
Ja, relative imports, darüber muss man

00:29:05.920 --> 00:29:07.700
auch noch sprechen. Ich bin ein großer Fan davon, aber

00:29:07.700 --> 00:29:08.820
offensiv sind die nicht so.

00:29:09.860 --> 00:29:11.240
Gut, da kommen wir vielleicht nach.

00:29:11.240 --> 00:29:12.140
Ja, ja, ja, okay.

00:29:13.220 --> 00:29:15.220
Also was macht denn Import jetzt überhaupt? Import macht,

00:29:15.740 --> 00:29:16.980
soll ich mal versuchen, soll ich mal

00:29:16.980 --> 00:29:19.280
mein Verständnis erklären und er korrigiert

00:29:19.280 --> 00:29:21.380
mich dann. Ja. Von wo importiert

00:29:21.380 --> 00:29:23.480
er denn überhaupt? Genau, also Import. Erstmal

00:29:23.480 --> 00:29:25.160
sucht Import ein,

00:29:25.380 --> 00:29:27.220
also wenn ich sage Import M, dann

00:29:27.220 --> 00:29:29.160
sucht das Import-System von Python

00:29:29.160 --> 00:29:30.580
nach etwas, das M heißt.

00:29:31.700 --> 00:29:33.460
Und zwar. Wo ist das denn? Ja, genau.

00:29:33.540 --> 00:29:35.320
Und zwar auf dem Python

00:29:35.320 --> 00:29:37.180
Path. Auf dem Path, ah.

00:29:37.180 --> 00:29:38.480
Da gibt es eine Variable, die heißt

00:29:38.480 --> 00:29:40.200
sys.pythonpath.

00:29:40.960 --> 00:29:42.940
Sys.path. Sys.path heißt die, oder?

00:29:43.060 --> 00:29:45.240
Okay, ich weiß, ich vergesse es jedes Mal wieder.

00:29:46.300 --> 00:29:47.040
Jedenfalls ist da

00:29:47.040 --> 00:29:48.420
eine Menge von Verzeichnissen drin

00:29:48.420 --> 00:29:51.200
und in der Reihenfolge, wie sie in diesem

00:29:51.200 --> 00:29:52.240
Path stehen,

00:29:52.960 --> 00:29:53.880
wird nach dem

00:29:53.880 --> 00:29:56.880
Namen M gesucht. Also 0 ist glaube ich

00:29:56.880 --> 00:29:57.740
der aktuelle irgendwie,

00:29:58.080 --> 00:30:01.140
das ist entweder vorne oder hinten, das ist immer

00:30:01.140 --> 00:30:02.460
Ich glaube 0, der erste ist immer

00:30:02.460 --> 00:30:04.560
wo du gerade bist. Das ist immer Punkt. Genau.

00:30:05.200 --> 00:30:07.000
Also die Datei, wo du gerade aufgeführt bist oder sowas

00:30:07.000 --> 00:30:08.780
und dann ist halt quasi, der sucht halt dann im

00:30:08.780 --> 00:30:10.900
ersten in eins, wo ab da was drin ist.

00:30:11.280 --> 00:30:12.760
Und der erste Hit wird dann genommen.

00:30:12.880 --> 00:30:14.580
Genau, der erste Hit wird dann genommen. Und in diesem Path

00:30:14.580 --> 00:30:17.020
können ganz viele verschiedene Sachen drin sein.

00:30:17.160 --> 00:30:18.660
Also die Installation, das

00:30:18.660 --> 00:30:20.720
Installationsverzeichnis des Interpreters und

00:30:20.720 --> 00:30:22.900
wenn man irgendwelche

00:30:22.900 --> 00:30:24.780
Environments aktiviert hat, dann sind die da alle drin.

00:30:25.140 --> 00:30:26.500
Man kann da auch selber Sachen reintun,

00:30:26.740 --> 00:30:28.420
braucht man manchmal, ist manchmal ganz nützlich.

00:30:30.860 --> 00:30:32.500
Ja, also da sind einfach viele Verzeichnisse drin.

00:30:32.500 --> 00:30:34.140
Also wenn man verschiedene Pakete haben will, die auch importiert werden können,

00:30:34.780 --> 00:30:36.180
dann muss man einfach da gucken. Das ist ein

00:30:36.180 --> 00:30:38.120
sys.path quasi in der Umgebungsvariante

00:30:38.120 --> 00:30:40.300
Das ist im Wesentlichen das, was Virtual

00:30:40.300 --> 00:30:42.200
Env macht. Er macht ein Verzeichnis, wo du

00:30:42.200 --> 00:30:44.220
deine Pakete reinlegen kannst und tut den in den

00:30:44.220 --> 00:30:46.160
Python-Path für dich. Genau, das heißt, wichtig, dass

00:30:46.160 --> 00:30:48.140
euer Path vernünftig konfiguriert ist, wenn ihr Python nutzt,

00:30:48.480 --> 00:30:50.240
weil wenn die falsche Reihenfolge drin ist, dann kann das

00:30:50.240 --> 00:30:51.520
sein, dass er im Path von Python

00:30:51.520 --> 00:30:54.060
2 sucht oder so, also wie es

00:30:54.060 --> 00:30:56.120
früher offenbar war. Und dann habt ihr ein Problem.

00:30:56.560 --> 00:30:56.640
Genau.

00:30:58.240 --> 00:31:00.160
Also, und er sucht diese ganzen Verzeichnisse durch und wenn

00:31:00.160 --> 00:31:02.040
da irgendwas drin ist, was diesem Namen m entspricht,

00:31:02.160 --> 00:31:04.200
also eine m.py oder ein Verzeichnis, was m heißt,

00:31:04.200 --> 00:31:06.580
was eine Init-Pi hat, oder in Python 3

00:31:06.580 --> 00:31:08.060
ein Verzeichnis, was

00:31:08.060 --> 00:31:10.320
das M heißt und Python-Dateien

00:31:10.320 --> 00:31:11.820
enthält, was keine Init-Pi hat,

00:31:12.660 --> 00:31:14.260
dann wird das

00:31:14.260 --> 00:31:16.300
als Modul importiert und

00:31:16.300 --> 00:31:18.080
in den aktuellen Namespace

00:31:18.080 --> 00:31:19.900
als Modul M übergeben.

00:31:20.120 --> 00:31:21.980
Wir haben gerade wirklich das schon in Python 2 und 3 diskutiert,

00:31:22.020 --> 00:31:23.640
das ist ja interessant. Ja, da gibt es Unterschiede.

00:31:23.700 --> 00:31:25.980
Ja, da gibt es auch interessante,

00:31:26.120 --> 00:31:27.780
also nochmal ein sehr interessanter Unterschied

00:31:27.780 --> 00:31:30.280
kommt mit Python 3.3, glaube ich,

00:31:30.300 --> 00:31:32.780
dazu, nämlich die Namespace-Only-Pakete.

00:31:34.020 --> 00:31:34.400
Erklär mal.

00:31:36.160 --> 00:31:36.920
Die gibt es.

00:31:37.420 --> 00:31:39.360
Also früher musste man ja immer die Init-PUI haben.

00:31:40.400 --> 00:31:41.660
Vor allen Dingen deswegen,

00:31:41.840 --> 00:31:43.280
damit halt nicht Verzeichnisse,

00:31:43.660 --> 00:31:45.240
die halt so heißen wie ein Standardmodul,

00:31:45.320 --> 00:31:46.380
halt das Standardmodul überschreiben.

00:31:48.000 --> 00:31:49.900
Und man halt damit dann quasi

00:31:49.900 --> 00:31:51.460
öffentlich

00:31:51.460 --> 00:31:53.400
sich dazu bekennt, dass das jetzt ein

00:31:53.400 --> 00:31:54.380
Paket sein soll.

00:31:56.020 --> 00:31:57.800
Also sozusagen, wenn man sich den Infus

00:31:57.800 --> 00:31:59.400
schließt, dann muss man das auch wirklich absichtlich gemacht haben.

00:32:00.460 --> 00:32:01.560
Und das ist aber

00:32:01.560 --> 00:32:02.780
teilweise blöd.

00:32:04.020 --> 00:32:05.840
weil oft will man vielleicht auch

00:32:05.840 --> 00:32:07.900
Dinge, die in einem Paket liegen, nicht in einem

00:32:07.900 --> 00:32:08.980
Verzeichnis haben zum Beispiel.

00:32:09.940 --> 00:32:11.440
Und also wenn es

00:32:11.440 --> 00:32:13.480
ein Init-Py gibt, dann

00:32:13.480 --> 00:32:15.000
ist das

00:32:15.000 --> 00:32:18.060
ja, dann, jetzt weiß ich

00:32:18.060 --> 00:32:19.680
nicht mehr die Stelle, wo das irgendwo drin steht,

00:32:19.760 --> 00:32:21.460
dass da drin gesucht werden soll, also

00:32:21.460 --> 00:32:23.760
Dispass, ja, aber es gibt auch noch irgendwie

00:32:23.760 --> 00:32:25.800
andere Stellen, glaube ich. Es gibt auch noch Module,

00:32:25.920 --> 00:32:27.820
die nicht da drin sind, zum Beispiel die

00:32:27.820 --> 00:32:29.860
Standard-Bibliotheks-Module

00:32:29.860 --> 00:32:31.700
sind, also es gibt welche, die sind irgendwie in

00:32:31.700 --> 00:32:33.780
das Python-Binary reinkompiliert und dann gibt es

00:32:33.780 --> 00:32:35.020
auch noch welche, die sind irgendwie

00:32:35.020 --> 00:32:37.700
woanders hingemarschelt, aber die liegen da auch irgendwo

00:32:37.700 --> 00:32:39.860
rum. Also die Rang-Python-Module,

00:32:40.000 --> 00:32:40.660
die nicht zählen.

00:32:41.760 --> 00:32:43.620
Das stimmt, das kann man, aber es gibt

00:32:43.620 --> 00:32:45.520
auch noch Dinge, Module, die sind halt einfach nur

00:32:45.520 --> 00:32:47.920
in der Shared-Library

00:32:47.920 --> 00:32:48.920
und nicht irgendwie Python.

00:32:50.020 --> 00:32:51.120
Aber da kommen wir gleich noch so weiter.

00:32:51.580 --> 00:32:53.680
Wo der Pycache und so weiter noch was dann kommt, aber egal.

00:32:55.060 --> 00:32:55.380
Genau.

00:32:56.300 --> 00:32:57.720
Aber man kann halt

00:32:57.720 --> 00:32:59.620
auch, es gibt auch Verzeichnisse und denen

00:32:59.620 --> 00:33:01.380
wird auch gesucht, wenn da keine NPY ist.

00:33:01.380 --> 00:33:02.560
Das ist allerdings dann irgendwie

00:33:02.560 --> 00:33:05.320
weiter hinten. Und

00:33:05.320 --> 00:33:07.260
alle, die den gleichen Namen haben, wenn da

00:33:07.260 --> 00:33:09.220
jetzt Sachen drin liegen, dann wird das zum

00:33:09.220 --> 00:33:11.100
gleichen Paket

00:33:11.100 --> 00:33:13.120
gehörig irgendwie aufgefasst und

00:33:13.120 --> 00:33:15.440
das ist dann so ein Namespace-Package.

00:33:15.580 --> 00:33:16.960
So ein Namespace-Mengeling.

00:33:17.200 --> 00:33:19.020
Und dann kannst du halt auch... Also wir erhalten

00:33:19.020 --> 00:33:20.800
fest, einfach immer eine Init-Pile.

00:33:21.260 --> 00:33:22.960
Ja, dann ist es sicher.

00:33:24.000 --> 00:33:25.260
Aber so kannst du halt

00:33:25.260 --> 00:33:27.040
auch Dinge in einem Paket haben, die in unterschiedlichen

00:33:27.040 --> 00:33:28.920
Verzeichnissen liegen, was halt manchmal auch ganz praktisch ist.

00:33:29.620 --> 00:33:30.720
Klar. Man kann das schon brauchen.

00:33:31.300 --> 00:33:31.560
Ja, okay.

00:33:32.560 --> 00:33:35.440
Okay, also was ist dann

00:33:35.440 --> 00:33:37.540
das haben wir gesagt, Package, es gibt auch

00:33:37.540 --> 00:33:39.480
ein dann dann Package, was steht

00:33:39.480 --> 00:33:39.760
denn da?

00:33:41.220 --> 00:33:42.880
Ist das Current Package? Genau.

00:33:44.500 --> 00:33:45.600
Ja, das ist das aktuelle Paket.

00:33:45.820 --> 00:33:47.200
Das ist ein Top-Level-Modul oder sowas, ja?

00:33:48.180 --> 00:33:49.220
Ja, äh,

00:33:49.420 --> 00:33:51.420
oh Gott, ich weiß auch nicht, ist es auch so? Ich glaube, also wenn es

00:33:51.420 --> 00:33:52.440
None ist, dann ist es ein Skript.

00:33:53.860 --> 00:33:55.540
Also vielleicht noch mal zu distinguieren zwischen Skript-Modul

00:33:55.540 --> 00:33:57.360
und Pakete oder so, wenn Package None ist,

00:33:57.380 --> 00:33:59.340
das ist nur ein Skript und wenn, er sucht halt dann, ob er so ein

00:33:59.340 --> 00:34:01.540
Package findet und wenn er eins findet, dann ist das Top-Level-Modul,

00:34:01.620 --> 00:34:03.000
von dem man dann importieren kann oder so.

00:34:04.560 --> 00:34:05.680
Und wenn es das nicht gibt, dann gibt es halt auch

00:34:05.680 --> 00:34:07.660
Fehler. Attempted Relative Import

00:34:07.660 --> 00:34:08.720
Beyond Top Level Package.

00:34:09.360 --> 00:34:11.460
Ja, das ist

00:34:11.460 --> 00:34:12.940
so eine Sache, die gibt es.

00:34:15.100 --> 00:34:15.660
Passiert mir auch

00:34:15.660 --> 00:34:17.580
regelmäßig. Echt, das passiert mir nie, das ist

00:34:17.580 --> 00:34:19.920
voll seltsam. Doch, passiert mir auch. Es gibt so Sachen, die

00:34:19.920 --> 00:34:21.560
machen Menschen offensichtlich

00:34:21.560 --> 00:34:23.480
unterschiedlich und das ist so eine Sache, die mache ich offenbar nicht.

00:34:24.060 --> 00:34:25.520
Also nicht, weil ich besser bin oder

00:34:25.520 --> 00:34:27.580
weil ich irgendwie das toller kann oder so, sondern

00:34:27.580 --> 00:34:29.780
weil es einfach was ist, was ich nicht benutze.

00:34:30.060 --> 00:34:32.100
Ja gut, aber wenn du relative Importe benutzt, wie du gerade gesagt hast.

00:34:32.100 --> 00:34:34.320
Ja, die liebe ich. Relative Importe sind voll gut.

00:34:34.540 --> 00:34:35.920
Ab und zu vertippt man sich ja mal oder hat irgendwie.

00:34:35.940 --> 00:34:38.080
Ja, aber also relative Importe, jetzt müssen wir

00:34:38.080 --> 00:34:40.200
über relative Importe sprechen. In Python 3

00:34:40.200 --> 00:34:42.040
und ich glaube in 2.7

00:34:42.040 --> 00:34:44.000
wurde das dann irgendwann geportet, gibt es

00:34:44.000 --> 00:34:46.080
die Möglichkeit zu sagen, from Punkt Import

00:34:46.080 --> 00:34:47.880
irgendwas, also from Punkt Import M.

00:34:48.020 --> 00:34:48.840
Oder vom dot dot.

00:34:49.140 --> 00:34:53.160
Oder auch from Punkt M

00:34:53.160 --> 00:34:54.320
Import irgendwas.

00:34:55.000 --> 00:34:56.100
Und dieser Punkt heißt halt eben

00:34:56.100 --> 00:34:58.080
immer aktuelles Verzeichnis.

00:34:58.240 --> 00:34:59.840
Also aktueller

00:34:59.840 --> 00:35:00.980
Pfad.

00:35:02.060 --> 00:35:04.140
Das heißt, wenn es in dieser

00:35:04.140 --> 00:35:06.160
Installation, die ich habe, zwei Module gibt, die M

00:35:06.160 --> 00:35:08.260
heißen, dann kann ich durch diesen

00:35:08.260 --> 00:35:10.220
relativen Import genauer sagen, welches

00:35:10.220 --> 00:35:12.220
ich meine. Ach, okay, doch,

00:35:12.400 --> 00:35:14.500
nee, das war der Unterschied zwischen Modulen und

00:35:14.500 --> 00:35:16.360
Packages. Module

00:35:16.360 --> 00:35:17.920
haben einen Pfad dran. Ja,

00:35:18.420 --> 00:35:19.960
ich glaube tatsächlich, das ist der entscheidende Unterschied.

00:35:20.860 --> 00:35:21.420
Ich glaube schon, ja.

00:35:23.120 --> 00:35:24.440
Genau, die Top-Level-Package

00:35:24.440 --> 00:35:26.080
ist halt irgendwie doch die Sache. Also wenn Package,

00:35:26.440 --> 00:35:28.340
wenn man ein Paket finden kann, also ein Top-Level

00:35:28.340 --> 00:35:30.360
finden kann, ja, mit diesem Dot-Dot, dann geht das halt.

00:35:30.440 --> 00:35:32.340
Aber wenn das None ist, weil man quasi auf der höchsten

00:35:32.340 --> 00:35:34.300
Ebene ist, dann gibt es halt Fehler zurück. Und das ist ja genau

00:35:34.300 --> 00:35:35.380
der Grund, warum das... Okay, das kann natürlich sein.

00:35:35.700 --> 00:35:38.220
Das kann natürlich sein, dass ich das einfach nie... Also für mich

00:35:38.220 --> 00:35:40.240
ist einfach Punkt, ja. Wenn ich sage from Punkt

00:35:40.240 --> 00:35:42.460
importen, dann weiß ich, das muss im aktuellen Verzeichnis

00:35:42.460 --> 00:35:44.240
liegen. Wenn ich sage from Punkt Punkt,

00:35:44.420 --> 00:35:46.360
dann weiß ich, das muss im Verzeichnis drüber liegen.

00:35:46.860 --> 00:35:48.540
Und für mich ist das einfach eine Möglichkeit,

00:35:48.880 --> 00:35:50.220
quasi in meinem Projekt zu

00:35:50.220 --> 00:35:52.480
navigieren. Aber, also ich sag mal so,

00:35:52.500 --> 00:35:54.180
das geht aber nur dann, wenn der Interpreter

00:35:54.180 --> 00:35:56.200
richtig aufgelöst ist. Weil wenn du tief drin bist

00:35:56.200 --> 00:35:58.320
und dann das Skript beispielsweise manuell ausführst,

00:35:58.340 --> 00:36:00.540
relativ tief drin, dann wird der ja diesen Fehler schmeißen.

00:36:00.680 --> 00:36:02.360
Wenn du diese Datei

00:36:02.360 --> 00:36:04.500
direkt aufrufst. Genau. Das kann man übrigens

00:36:04.500 --> 00:36:06.260
verhindern, indem man einfach sagt, Python minus M

00:36:06.260 --> 00:36:08.480
und dann dieses Modul dann

00:36:08.480 --> 00:36:09.780
innerhalb von dem Pfad aufrufen. Genau.

00:36:10.220 --> 00:36:12.480
Die meisten meiner Projekte sind ja aber in einem Django-Umfeld.

00:36:12.880 --> 00:36:14.640
Ja. Und da bin ich nie in der Verlegenheit,

00:36:14.740 --> 00:36:16.520
diese Sachen direkt aufzurufen, sondern die werden

00:36:16.520 --> 00:36:17.520
dann entweder über

00:36:17.520 --> 00:36:20.280
einen Run-Server aufgerufen oder über einen Test

00:36:20.280 --> 00:36:21.080
oder über einen

00:36:21.080 --> 00:36:24.400
Command. Auch da ist der Pfad, ja,

00:36:24.520 --> 00:36:26.220
musst du ja richtig definieren. Ja, aber der

00:36:26.220 --> 00:36:28.280
Pfad ist immer festgemacht an der Manage-Pile.

00:36:28.340 --> 00:36:30.260
Genau. Das heißt,

00:36:30.460 --> 00:36:32.400
das weiß ich. Ich weiß, wo der Pfad...

00:36:32.400 --> 00:36:34.240
Ja, aber das ist ja auch Python-M, Package.Module

00:36:34.240 --> 00:36:36.140
oder so. Genau. Und deshalb

00:36:36.140 --> 00:36:38.160
ist das vielleicht was, was einfach in meiner

00:36:38.160 --> 00:36:40.000
täglichen Arbeit nicht so auftritt, dass ich da

00:36:40.000 --> 00:36:42.320
mich quasi vernavigiere,

00:36:42.660 --> 00:36:44.140
weil meine Projekte

00:36:44.140 --> 00:36:46.280
eben immer eine feste

00:36:46.280 --> 00:36:48.020
Wurzel haben und darunter kann ich

00:36:48.020 --> 00:36:49.520
mich bewegen, wie ich möchte.

00:36:50.880 --> 00:36:52.360
Ja, mir passiert das halt vor allen Dingen

00:36:52.360 --> 00:36:53.260
dann, also einmal

00:36:53.260 --> 00:36:56.280
in Paketen habe ich oft gerne Tests

00:36:56.280 --> 00:36:58.220
in einem anderen Verzeichnis. Also da gibt es

00:36:58.220 --> 00:37:00.420
sind Tests nicht innerhalb von dem Projekt

00:37:00.420 --> 00:37:02.500
selber, sondern liegen halt in einem Test-Directory.

00:37:02.880 --> 00:37:04.360
Wenn da irgendwas nicht richtig konfiguriert ist, dann passiert

00:37:04.360 --> 00:37:05.800
das halt schon mal. Ja, genau, klar.

00:37:06.340 --> 00:37:08.300
Und wo es mir halt auch ab und zu passiert ist,

00:37:08.300 --> 00:37:10.580
ist halt in Jupyter-Notebooks,

00:37:10.680 --> 00:37:12.360
weil die liegen halt auch wieder in einem anderen Verzeichnis.

00:37:12.580 --> 00:37:13.800
Und die sind halt auch irgendwo. Genau.

00:37:14.360 --> 00:37:16.380
Und deswegen sehe ich das halt

00:37:16.380 --> 00:37:18.220
häufiger mal. Bei diesem Importer

00:37:18.220 --> 00:37:20.200
auch ganz interessant. Ich glaube, das kommt dann wirklich darauf an, wenn der

00:37:20.200 --> 00:37:22.320
Name des Moduls Punkte enthält

00:37:22.320 --> 00:37:24.000
oder halt nicht. Weil wenn er

00:37:24.000 --> 00:37:26.220
Punkte hat, dann... Ach so, wenn der Name des

00:37:26.220 --> 00:37:28.300
Moduls, also wenn das Modul quasi

00:37:28.300 --> 00:37:30.120
m.x.y.

00:37:30.260 --> 00:37:31.580
Genau, dann ist es halt

00:37:31.580 --> 00:37:33.100
ein Part, ein Paket.

00:37:33.100 --> 00:37:34.640
So was vermeiden wir jetzt einfach halt noch.

00:37:34.780 --> 00:37:37.000
Ja genau, aber nein, andersrum, wenn es halt keinen Punkt

00:37:37.000 --> 00:37:38.940
mehr hat, dann muss es eigentlich schon

00:37:38.940 --> 00:37:40.620
Top-Level sein, weil dann

00:37:40.620 --> 00:37:41.360
kannst du ja nicht.

00:37:42.860 --> 00:37:43.380
Ah, okay.

00:37:43.800 --> 00:37:47.020
Aber man kann ja jetzt auch so Dinge tun

00:37:47.020 --> 00:37:47.820
wie, man sagt

00:37:47.820 --> 00:37:50.280
from m import

00:37:50.280 --> 00:37:52.040
x oder so.

00:37:53.020 --> 00:37:54.800
Habt ihr schon mal Skriptnamen mit Punkten verwendet?

00:37:54.900 --> 00:37:55.640
also mit mehreren Punkten drin.

00:37:55.640 --> 00:37:57.060
Nee, das ist das, was ich gerade jetzt überlege,

00:37:57.220 --> 00:38:00.820
ob ich eine Datei mit Punkten drin hätte,

00:38:00.900 --> 00:38:02.000
ohne also Punkt P, Y.

00:38:02.340 --> 00:38:04.380
Ich glaube, das kann zu Problemen führen, oder?

00:38:04.400 --> 00:38:05.760
Ich glaube auch, dass das zu Problemen führt.

00:38:05.860 --> 00:38:07.620
Und das würde ich auch vermeiden einfach.

00:38:08.880 --> 00:38:09.940
Ja, interessant.

00:38:10.400 --> 00:38:11.760
Stimmt, das habe ich auch noch nicht ausprobiert.

00:38:12.180 --> 00:38:14.040
Das müssen wir, das wird dann die nächste Episode.

00:38:14.160 --> 00:38:15.640
Was passiert eigentlich, wenn man einen Punkt eingibt?

00:38:17.300 --> 00:38:17.660
Ja, genau.

00:38:17.880 --> 00:38:20.420
Ach so, genau, die Form import M

00:38:20.420 --> 00:38:23.060
ist ja noch vergleichsweise offensichtlich.

00:38:23.180 --> 00:38:24.000
Aber jetzt hat der Jochen eben gesagt,

00:38:24.000 --> 00:38:25.440
Was ist denn, wenn ich sage, from m import x?

00:38:25.680 --> 00:38:25.880
Genau.

00:38:27.140 --> 00:38:29.780
Und was dann halt für mich passiert ist,

00:38:30.240 --> 00:38:31.280
er importiert erst m

00:38:31.280 --> 00:38:34.100
und guckt dann in m nach,

00:38:34.180 --> 00:38:35.600
ob es da etwas gibt, was x heißt

00:38:35.600 --> 00:38:37.140
und gibt mir das als Import.

00:38:37.880 --> 00:38:38.980
Aber das stimmt nicht ganz.

00:38:40.100 --> 00:38:41.320
Weil es kann nämlich auch,

00:38:41.500 --> 00:38:43.380
man kann auch from m import x machen,

00:38:43.500 --> 00:38:44.720
wenn es in m gar kein x gibt.

00:38:46.500 --> 00:38:47.240
Weil eben,

00:38:47.780 --> 00:38:49.380
wie angekündigt,

00:38:50.140 --> 00:38:52.140
wenn m ein Verzeichnis ist,

00:38:52.140 --> 00:38:53.040
was eine InitPy enthält,

00:38:54.000 --> 00:38:55.940
Dann kriege ich aus dem Import M

00:38:55.940 --> 00:38:57.620
alles das raus, was in der InitPy drin ist.

00:38:58.280 --> 00:38:59.980
Aber from M Import X kann dann

00:38:59.980 --> 00:39:01.600
die Datei X.py sein, also

00:39:01.600 --> 00:39:03.240
M-X.py

00:39:03.240 --> 00:39:05.760
und die kann ich mit, also an die

00:39:05.760 --> 00:39:07.440
komme ich dran, ja, from M Import X.

00:39:08.080 --> 00:39:09.720
Aber die ist nicht in M selbst

00:39:09.720 --> 00:39:11.920
enthalten. Also wenn ich nur Import M mache, gibt es nicht M.x.

00:39:12.860 --> 00:39:13.840
Kann so sein.

00:39:14.540 --> 00:39:14.900
Deshalb

00:39:14.900 --> 00:39:17.480
ist es dann doch

00:39:17.480 --> 00:39:19.800
noch gleich ein bisschen anders. Also man muss

00:39:19.800 --> 00:39:21.760
eigentlich immer auf die Datei zeigen, die man

00:39:21.760 --> 00:39:23.460
haben möchte. Ja, aber genau, das fand ich auch

00:39:23.460 --> 00:39:25.160
Das hat mich auch überrascht, das wusste ich nicht,

00:39:25.360 --> 00:39:26.760
wenn man sagt, vom M-Import X,

00:39:27.500 --> 00:39:28.660
ich weiß nicht, was ich vorher gedacht habe,

00:39:28.940 --> 00:39:30.700
aber ich dachte, das holt das X da raus

00:39:30.700 --> 00:39:32.260
und dann hat man das halt im eigenen Namespace.

00:39:32.680 --> 00:39:34.720
Aber eben, es macht halt eher sowas wie Import M,

00:39:35.040 --> 00:39:36.820
dann sagt es X gleich M.X

00:39:36.820 --> 00:39:37.920
und dann sagt es Del M.

00:39:38.980 --> 00:39:40.820
Und das ist halt eher so das, was tatsächlich passiert.

00:39:40.980 --> 00:39:43.340
Und das ist auch schon so, ui, ui, okay.

00:39:43.860 --> 00:39:44.860
Also wenn es nicht geht, macht er doch was anderes,

00:39:45.060 --> 00:39:46.320
weil dann holt er sich doch noch die Detail.

00:39:46.820 --> 00:39:47.320
Ja, ja, ja.

00:39:49.260 --> 00:39:51.200
Achso, und es ist natürlich alles übrigens noch gecached.

00:39:51.200 --> 00:39:53.020
Ja, also man kann so oft Import M machen,

00:39:53.100 --> 00:39:57.060
möchte es wird nur einmal gelesen die datei und das wird da wo wir das dann reingeschrieben in

00:39:57.060 --> 00:40:15.180
das dictionary der offenen der geladenen module das heißt irgendwie punkt das ist auch so eine

00:40:15.180 --> 00:40:16.380
eine geschichte das kann man auch schön sehen

00:40:16.380 --> 00:40:17.150
verwenden. Also

00:40:17.150 --> 00:40:19.730
manchmal braucht man ja, also Singleton,

00:40:19.950 --> 00:40:22.350
ein ehrlich gesagt überschätztes

00:40:22.350 --> 00:40:23.350
Cooles.

00:40:23.350 --> 00:40:26.270
Es hat einen total coolen Namen, deswegen wollen

00:40:26.270 --> 00:40:28.050
es die Leute immer verwenden. Aber tatsächlich gibt es

00:40:28.050 --> 00:40:30.170
manchmal braucht man das. Manchmal braucht man es

00:40:30.170 --> 00:40:31.890
tatsächlich. Meistens nicht. Meistens

00:40:31.890 --> 00:40:34.390
eher nicht. Genau, aber Module sind immer Singletons.

00:40:34.570 --> 00:40:36.210
Ganz genau. Und das ist

00:40:36.210 --> 00:40:38.250
tatsächlich die eleganteste Art, die ich kenne, wie man das

00:40:38.250 --> 00:40:40.230
macht. Und es ist auch manchmal total nervig.

00:40:40.690 --> 00:40:41.310
Ja, aber

00:40:41.310 --> 00:40:44.330
ich habe da vorher

00:40:44.330 --> 00:40:46.410
schon, also meistens habe ich dann Borg-Pattern verwendet

00:40:46.410 --> 00:40:47.990
oder halt irgendwas in der Richtung

00:40:47.990 --> 00:40:50.210
oder manchmal halt auch, wenn ich nicht Borg

00:40:50.210 --> 00:40:52.270
wollte, sondern direkt Singleton, dann wird es aber schon

00:40:52.270 --> 00:40:54.290
hakelig, dann kann man das irgendwie, dann muss

00:40:54.290 --> 00:40:56.210
man schon so Meta-Klassen oder sonst irgendwie sowas,

00:40:56.250 --> 00:40:58.110
muss man so Dinge, wo man sich hinterher so ein bisschen

00:40:58.110 --> 00:41:00.230
schmutzig fühlt, irgendwie machen und

00:41:00.230 --> 00:41:02.290
bis ich dann irgendwann mal, ich weiß gar nicht, wo ich das gesehen habe,

00:41:02.330 --> 00:41:04.130
den Trick, so dass jemand meinte, ja, ja, Module sind doch

00:41:04.130 --> 00:41:06.370
sowieso Singleton, es sind doch einfach globale Variablen

00:41:06.370 --> 00:41:06.830
in einem Modul.

00:41:07.970 --> 00:41:09.190
Ja, stimmt ja.

00:41:10.210 --> 00:41:11.990
Moment, das muss man ja nochmal genau erklären,

00:41:12.090 --> 00:41:13.970
warum das ein Singleton ist. Aber Jochen, wenn du dann

00:41:13.970 --> 00:41:15.610
wenn du dann das Pattern richtig ausführen musst,

00:41:15.710 --> 00:41:17.370
musst du dann noch in dem Modul noch ein Get

00:41:17.370 --> 00:41:19.630
irgendwas machen.

00:41:19.910 --> 00:41:21.490
Falls das anlegt oder

00:41:21.490 --> 00:41:23.810
Falls jemand

00:41:23.810 --> 00:41:25.870
versucht darum rumzukommen.

00:41:26.130 --> 00:41:27.330
Ja, genau. Eigentlich ja.

00:41:28.950 --> 00:41:29.670
Jetzt der Dominik

00:41:29.670 --> 00:41:30.910
möchte es gerne erklärt haben.

00:41:31.150 --> 00:41:33.590
Also ein Singleton macht irgendwie,

00:41:33.810 --> 00:41:35.570
dass er guckt, ob es schon ein Objekt gibt,

00:41:35.810 --> 00:41:37.750
das dieses Typen ist und gibt das dann

00:41:37.750 --> 00:41:39.730
zurück, wenn es schon gibt. Und sonst stellt er einfach das eine,

00:41:39.790 --> 00:41:41.790
was es nur geben darf. Ja, Singleton heißt ja erstmal nur,

00:41:41.790 --> 00:41:43.790
es gibt während der Ausführung des Programms

00:41:43.790 --> 00:41:44.770
nur eins davon.

00:41:45.510 --> 00:41:46.910
Egal was davon ist.

00:41:46.910 --> 00:41:49.030
Und Borg ist, dass es gibt ganz viele

00:41:49.030 --> 00:41:50.910
davon, aber die sind alle dieselben Eigenschaften.

00:41:52.590 --> 00:41:52.770
Immer.

00:41:53.350 --> 00:41:55.170
Ja, da wird der

00:41:55.170 --> 00:41:56.970
State geshared, aber es ist nicht

00:41:56.970 --> 00:41:58.390
die gleiche Instanz tatsächlich. Es können

00:41:58.390 --> 00:42:01.050
unterschiedliche Instanzen sein, aber der State ist immer der gleiche.

00:42:01.070 --> 00:42:03.010
Genau, das heißt, die Eigenschaften sind alle dieselben über alle Instanzen

00:42:03.010 --> 00:42:04.130
hinweg. Ja, genau.

00:42:04.870 --> 00:42:06.870
Okay. Und Singleton kriegt mir

00:42:06.870 --> 00:42:09.210
eben durch ein Modul einfach hin. Also ich mache eine Datei

00:42:09.210 --> 00:42:10.510
singleton.py

00:42:10.510 --> 00:42:12.750
und da schreibe ich rein x gleich 2.

00:42:13.790 --> 00:42:15.670
dann mache ich Import Singleton und dann sage ich

00:42:15.670 --> 00:42:16.430
Singleton.x

00:42:16.430 --> 00:42:19.790
und das ist jetzt diese Instanz,

00:42:20.290 --> 00:42:21.870
dieses Punkt X gibt es nur genau

00:42:21.870 --> 00:42:23.790
einmal, weil der Python-Interpreter

00:42:23.790 --> 00:42:25.350
eben beim Import

00:42:25.350 --> 00:42:27.690
jede Datei nur einmal

00:42:27.690 --> 00:42:28.930
importiert, um es mal so zu sagen.

00:42:29.170 --> 00:42:31.610
Wenn eine Datei einmal importiert wurde, dann

00:42:31.610 --> 00:42:33.690
liegt die im Cache und dann, wenn du

00:42:33.690 --> 00:42:35.710
dann Import Singleton sagst, kriegst du wieder die aus dem Cache.

00:42:36.750 --> 00:42:37.630
Mit allen ihren

00:42:37.630 --> 00:42:39.310
Eigenschaften. Das heißt,

00:42:40.310 --> 00:42:41.710
du kriegst es mit dem,

00:42:42.830 --> 00:42:44.850
Du kannst es nicht ganz einfach machen,

00:42:44.970 --> 00:42:46.690
dass du diese Datei nochmal importierst.

00:42:47.030 --> 00:42:48.850
Weil Python halt sagt, ja, die kenne ich ja schon.

00:42:49.630 --> 00:42:50.550
Brauche ich nicht nochmal importieren.

00:42:51.270 --> 00:42:52.670
Also, weil das Moment, also das,

00:42:52.810 --> 00:42:54.730
weil dieser Import, das ist ein, was ist das?

00:42:54.810 --> 00:42:56.270
Ein Modultyp dann, wenn du ein Modul hast?

00:42:56.390 --> 00:42:57.370
Genau, das heißt Module.

00:42:58.330 --> 00:43:00.510
Und dieser Modultyp ist einfach die Zeichenkette,

00:43:00.670 --> 00:43:02.510
keine Ahnung, von dem, was ist?

00:43:02.730 --> 00:43:04.870
Ja, das Ausgeführte, das ist eigentlich der ausgeführte Code,

00:43:04.930 --> 00:43:06.870
der da drin ist, mit so einer Closure, die außen rum.

00:43:07.590 --> 00:43:08.590
Weil sonst könntest du keine Daten haben.

00:43:08.590 --> 00:43:10.750
Aber das wird dann doch gecastet, was dann Eval wäre?

00:43:10.750 --> 00:43:11.970
Oder, das habe ich ja nicht genau klar.

00:43:12.390 --> 00:43:13.990
Ja, im Endeffekt macht es ein E-Wahl, ja.

00:43:14.150 --> 00:43:17.410
Aber halt ein sehr gut verstecktes.

00:43:19.130 --> 00:43:20.870
Ja gut, ich meine, Import heißt,

00:43:20.990 --> 00:43:23.050
führ mal bitte den Code in der Datei XYZ aus.

00:43:23.430 --> 00:43:24.690
Also musst du ihn irgendwie ausführen.

00:43:24.870 --> 00:43:26.070
Irgendwo muss da ein E-Wahl drin sein.

00:43:28.230 --> 00:43:30.050
Aber es ist eben hinter so vielen Schichten versteckt,

00:43:30.110 --> 00:43:30.650
dass du es nicht siehst.

00:43:30.770 --> 00:43:32.770
Also was der macht ist, er lädt diese Datei.

00:43:32.850 --> 00:43:33.650
Immer wieder und immer wieder.

00:43:34.990 --> 00:43:35.830
Er lädt sie einmal.

00:43:36.130 --> 00:43:37.350
Aber wenn ich aus mehreren Stellen das habe,

00:43:37.410 --> 00:43:38.050
was ist denn dann passiert?

00:43:38.670 --> 00:43:41.830
Beim ersten Import Singleton wird diese Datei geladen

00:43:41.830 --> 00:43:43.750
und ausgeführt. Ja. Und das

00:43:43.750 --> 00:43:45.730
Ergebnis dieser Ausführung wird als Module

00:43:45.730 --> 00:43:47.710
Singleton. Ja. Abgelegt

00:43:47.710 --> 00:43:49.450
in diesem SysModules Cache.

00:43:49.590 --> 00:43:51.450
Und vielleicht wird dann da ein PyCache draus gebracht,

00:43:51.550 --> 00:43:53.510
PyC-Files oder so, hat das direkt da?

00:43:53.590 --> 00:43:55.470
Ja, nee, das ist nur eine interne

00:43:55.470 --> 00:43:57.750
Repräsentation. Das ist halt eben ein internes,

00:43:58.370 --> 00:43:59.530
das ist eine Klasse, die heißt Module

00:43:59.530 --> 00:44:00.890
und die hat Eigenschaften. Ja.

00:44:01.930 --> 00:44:03.650
Und wenn du dann

00:44:03.650 --> 00:44:05.450
nochmal Import Singleton machst, zum Beispiel in einer

00:44:05.450 --> 00:44:07.570
Datei oder zu einem späteren Zeitpunkt

00:44:07.570 --> 00:44:09.270
oder in einer Schleife, wo du es tausendmal machst,

00:44:09.770 --> 00:44:11.510
dann wird nicht nochmal diese

00:44:11.510 --> 00:44:13.490
Datei singleton.py geladen, sondern dann

00:44:13.490 --> 00:44:15.210
guckt er eben in seinen sysmodules.cache und sagt,

00:44:15.310 --> 00:44:16.650
ah ja, den Namen singleton kenne ich schon.

00:44:16.930 --> 00:44:19.330
Beim ersten Import lädt er das

00:44:19.330 --> 00:44:20.970
tatsächlich in den Pycify rein.

00:44:21.130 --> 00:44:22.510
Das heißt, er macht aus Bytecode draus,

00:44:22.870 --> 00:44:25.270
er komponiert das quasi und er liest das

00:44:25.270 --> 00:44:26.550
quasi einmal aus als String und man

00:44:26.550 --> 00:44:29.290
macht dann Bytecode draus und dann

00:44:29.290 --> 00:44:31.310
schreibt er das in Pycache rein und von da

00:44:31.310 --> 00:44:33.050
versucht er dann erstmal zu laden aus Pyc.

00:44:34.310 --> 00:44:34.530
Genau.

00:44:35.010 --> 00:44:37.210
Und das war jetzt ein Marshall-Objekt?

00:44:37.490 --> 00:44:39.690
Nein, das Ergebnis der Ausführung

00:44:39.690 --> 00:44:40.970
ist das, was dann das Modul ist.

00:44:41.510 --> 00:44:43.770
der Code des Moduls kann dann schon

00:44:43.770 --> 00:44:45.450
wieder weg sein, weil den brauchst du dann gar nicht mehr.

00:44:45.930 --> 00:44:48.010
Wenn du irgendwo ein Dev machst oder ein Class machst,

00:44:48.350 --> 00:44:49.770
da sind dann so Bytecode-Objekte

00:44:49.770 --> 00:44:51.530
dran, weil die müssen ja nochmal ausgeführt werden.

00:44:52.150 --> 00:44:53.190
Aber das Modul selbst,

00:44:54.530 --> 00:44:55.810
das, was in der Datei

00:44:55.810 --> 00:44:57.750
drin steht, das muss gar nicht mehr da sein.

00:44:57.850 --> 00:44:59.790
Also wenn du einfach nur eine Datei hast, die ganz viele Sachen

00:44:59.790 --> 00:45:01.710
ausrechnet und am Ende

00:45:01.710 --> 00:45:03.650
aber nur ein Wert rauskommt, dann ist

00:45:03.650 --> 00:45:05.670
dieser Code nicht mehr da. Es ist nur noch

00:45:05.670 --> 00:45:07.730
das Ergebnis da. Also das Ergebnis

00:45:07.730 --> 00:45:09.610
der Ausführung dieser Datei ist dann das, was

00:45:09.610 --> 00:45:11.650
in das Modul. Okay, und was

00:45:11.650 --> 00:45:12.930
wird dann in die PyC-File reingeschrieben?

00:45:13.310 --> 00:45:15.310
Die PyC-Files sind so eine

00:45:15.310 --> 00:45:17.230
Zwischendurch-Optimierung, weil die

00:45:17.230 --> 00:45:19.550
die enthalten

00:45:19.550 --> 00:45:21.490
so einen vorkompilierten Bytecode und der

00:45:21.490 --> 00:45:23.810
ist schneller zu laden als eine .py-Datei.

00:45:23.930 --> 00:45:25.810
Und das ist ein Marschalt-

00:45:25.810 --> 00:45:27.390
Object, also wir hatten ganz am Anfang einmal kurz

00:45:27.390 --> 00:45:29.290
Marschalt gesagt, was ist das überhaupt? Einmal kurz

00:45:29.290 --> 00:45:31.130
nochmal den kleinen Exkurs. Jochen,

00:45:31.250 --> 00:45:33.510
erklär du doch mal. Ach ja, damals

00:45:33.510 --> 00:45:35.490
genau,

00:45:35.690 --> 00:45:37.250
es ist im Grunde Marschaling

00:45:37.250 --> 00:45:38.330
ist eigentlich ein anderes Wort,

00:45:39.190 --> 00:45:57.330
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.330 --> 00:46:15.510
Und da gab es zwei Module, die ersten waren halt Marshall, das heißt auch so, das gibt es immer noch in der Standardbibliothek und Shelf, Shelf war schon damals nicht so richtig populär, also Marshall kann man immer noch verwenden, kann halt nur relativ wenige Datentypen und in neueren Python-Versionen verwendet man da eigentlich immer Pickle für.

00:46:15.510 --> 00:46:17.210
aber das ist halt im Grunde das, was es macht, wenn man

00:46:17.210 --> 00:46:19.350
sagt, vom Pickle

00:46:19.350 --> 00:46:21.110
oder wenn man sagt

00:46:21.110 --> 00:46:22.790
cpickle.dump

00:46:22.790 --> 00:46:25.170
oder so, dann wird das halt in String oder Dump

00:46:25.170 --> 00:46:27.330
in einen Teil geschrieben und dann hat man halt

00:46:27.330 --> 00:46:29.370
eine in einem String serialisierte Form von

00:46:29.370 --> 00:46:30.470
zum Beispiel irgendwie Code.

00:46:31.050 --> 00:46:33.010
Also mittlerweile nimmt, glaube ich, sogar Dill oder sowas,

00:46:33.210 --> 00:46:35.410
dass man irgendwie import Dill as Pickle

00:46:35.410 --> 00:46:36.750
oder so, also neue Version.

00:46:37.010 --> 00:46:38.390
Als Third-Party-Package irgendwie.

00:46:39.210 --> 00:46:39.530
Schön.

00:46:40.310 --> 00:46:43.030
Okay, aber ein Marschalt-Objekt, falls ihr das irgendwo findet,

00:46:43.030 --> 00:46:44.470
ist quasi eine serialisierte

00:46:44.470 --> 00:46:46.610
Form von dem

00:46:46.610 --> 00:46:48.530
Speisen-Code, der da gelaufen ist.

00:46:49.270 --> 00:46:49.450
Genau.

00:46:50.130 --> 00:46:52.230
Okay, jetzt haben wir es irgendwo geladen,

00:46:52.290 --> 00:46:54.590
haben wir es gefunden. Was importiert ihr dann? Was ruft ihr dann auf?

00:46:55.590 --> 00:46:56.270
Ja, das Ergebnis

00:46:56.270 --> 00:46:57.890
dieser Ausführung.

00:46:57.890 --> 00:46:59.990
Also import.dott, dann dann import.

00:47:00.390 --> 00:47:00.770
Dann dann

00:47:00.770 --> 00:47:03.790
crawl. In diese Funktion

00:47:03.790 --> 00:47:05.190
kommen dann halt die Argumente rein, die

00:47:05.190 --> 00:47:07.190
Ja, nee, das kann ja alles möglich sein.

00:47:07.610 --> 00:47:09.930
Du kannst ja auch beliebige Objekte in der Datei

00:47:09.930 --> 00:47:11.870
reinschreiben. Du kannst auch ein Modul machen,

00:47:11.950 --> 00:47:13.710
was einfach nur einen String enthält, wo irgendwelche

00:47:13.710 --> 00:47:14.470
Binärdaten drin sind.

00:47:16.110 --> 00:47:17.790
Macht man ja manchmal, weil man Testdaten

00:47:17.790 --> 00:47:18.210
braucht.

00:47:19.950 --> 00:47:21.750
Das Modul hast, wo einfach so ein paar Strings

00:47:21.750 --> 00:47:23.910
drin sind. Und wenn die eben ausgeführt werden,

00:47:23.990 --> 00:47:25.010
dann werden die halt so ein

00:47:25.010 --> 00:47:27.950
String-Objekt in Python mit einem Namen

00:47:27.950 --> 00:47:29.790
und genau diese Sachen,

00:47:30.250 --> 00:47:31.850
also im Endeffekt ist das halt so ein Dictionary,

00:47:31.930 --> 00:47:33.610
was da drin ist. So ein Unterstrich, Unterstrich, Dikt,

00:47:33.790 --> 00:47:35.690
Unterstrich, Unterstrich. Das hat natürlich noch

00:47:35.690 --> 00:47:36.670
mehr so Attribute.

00:47:37.430 --> 00:47:39.490
Der Path ist da drin und

00:47:39.490 --> 00:47:41.710
der ursprüngliche Importname

00:47:41.710 --> 00:47:43.870
und der Dockstring wird rausgelesen

00:47:43.870 --> 00:47:45.810
und so weiter. Also diese ganzen Sachen, die halt

00:47:45.810 --> 00:47:47.690
so passieren, wenn Python was ausführt,

00:47:49.130 --> 00:47:49.890
die passieren da auch.

00:47:50.110 --> 00:47:51.550
Alles, was Python langsam macht.

00:47:51.990 --> 00:47:53.470
Alles, was Python awesome macht.

00:47:55.090 --> 00:47:55.450
Ja.

00:47:56.190 --> 00:47:57.730
Genau. Und das Ergebnis dieser Ausführung

00:47:57.730 --> 00:47:59.190
ist halt dann das, was das Modul ist.

00:47:59.430 --> 00:48:01.430
Das zusammengefasste Modul. Da gibt es Modul.doc

00:48:01.430 --> 00:48:02.590
und Modul.tikt und Modul.

00:48:03.390 --> 00:48:05.890
Was weiß ich nicht noch alles. .name und .path

00:48:05.890 --> 00:48:07.270
und .package.

00:48:07.730 --> 00:48:09.730
Genau. Also alle diese Sachen, die halt dazu gehören.

00:48:09.810 --> 00:48:11.450
Aber das ist dann schon ein Python-Objekt.

00:48:11.450 --> 00:48:33.070
Also es ist keine Datei mehr, sondern es ist dann ein fertiges Python-Objekt. Und auch diese Klassen, die müssen ja erzeugt werden und wenn es so Meta-Klassen hat, dann müssen die ausgeführt werden. Also alles das, was da, ja, es ist quasi wie wenn man die Datei in den Interpreter eingibt und dann alles, was da rauskommt, eben zusammenfasst in eine Sache gepackt.

00:48:33.070 --> 00:48:41.070
Also es ist eigentlich von der Organisationsebene her, finde ich, sehr sauber, weil alles, was in der Datei drin ist, ist dann eben als Python-Objekt verfügbar.

00:48:43.310 --> 00:48:52.370
Und das ist auch für mich so ein bisschen der Grund, warum man das braucht, dass ich halt einfach bestimmte Python-Objekte oder bestimmte Dinge in andere Dateien reinschreiben möchte.

00:48:52.670 --> 00:48:56.350
Und diese Dateien sollen in anderen Verzeichnissen liegen, damit ich nicht die Übersicht verliere.

00:48:57.770 --> 00:49:01.350
Und ja, so, das ist Import.

00:49:03.070 --> 00:49:05.790
Und jetzt gibt es noch Importlib.

00:49:07.090 --> 00:49:12.170
Ja, das wird ja aufgerufen sogar, also Import wird ja bei Import aufgerufen, wenn man es nicht überschrieben hat.

00:49:12.170 --> 00:49:22.210
Import ist eigentlich syntaktisch, genau, das kommt ja auch noch dazu, das ist ja in dem Artikel, glaube ich, nicht drin, aber in der Diskussion war es dann drin, man kann das auch überschreiben, man kann auch selber eingreifen in den Importprozess.

00:49:23.290 --> 00:49:29.710
Also Dinge, die man, auf der Liste der Dinge, die man unbedingt tun sollte, ist das ganz, ganz, ganz weit unten.

00:49:32.990 --> 00:49:46.430
Es gibt Importlib und in Python 3 irgendwas hat auch dieser Prozess, dieser Importprozess ist quasi zu einer Python-Funktionalität geworden, den man programmatisch aufrufen kann, was sehr nützlich ist.

00:49:48.290 --> 00:49:59.770
Und diese Statement Import M ist quasi nur noch ein syntaktischer Zucker für Importlib Punkt, keine Ahnung, unterstrich Import, ja, irgendwie sowas.

00:50:02.390 --> 00:50:04.610
das Coole daran ist, dass man

00:50:04.610 --> 00:50:06.630
eben jetzt in diesen Prozess eingreifen kann.

00:50:06.790 --> 00:50:08.630
Und das ist insbesondere dann für zwei Sachen nützlich.

00:50:08.630 --> 00:50:10.790
Die erste Sache, für die es super nützlich ist,

00:50:12.570 --> 00:50:14.630
da muss ich jetzt leider auf meine eigenen

00:50:15.310 --> 00:50:16.710
Dinge verweisen, da werde ich

00:50:16.710 --> 00:50:18.850
in Kürze ein Video dazu hochladen.

00:50:19.170 --> 00:50:20.450
Kommt dann natürlich in die Show noch.

00:50:20.610 --> 00:50:20.890
Oh ja.

00:50:22.050 --> 00:50:23.670
Wenn man etwas neu laden möchte.

00:50:25.930 --> 00:50:26.330
Weil

00:50:26.330 --> 00:50:28.550
wir haben ja eben besprochen, wenn ich Import M

00:50:28.550 --> 00:50:30.650
mache, dann kriege ich immer das, wird es einmal geladen

00:50:30.650 --> 00:50:31.190
und dann nie wieder.

00:50:32.110 --> 00:50:34.330
Man ist ja jetzt oft als Softwareentwickler in so einer Situation,

00:50:34.470 --> 00:50:36.330
dass man Dateien dann verändert und die

00:50:36.330 --> 00:50:37.910
eigentlich sofort

00:50:37.910 --> 00:50:40.490
haben möchte, ohne dass man das Programm

00:50:40.490 --> 00:50:42.590
neu startet. Und um das hinzukriegen,

00:50:43.330 --> 00:50:44.530
habe ich mir halt so ein bisschen

00:50:44.530 --> 00:50:46.490
einen Glue-Code geschrieben, der Dateien

00:50:46.490 --> 00:50:48.510
überwacht und wenn die sich ändern, dann wird da halt

00:50:48.510 --> 00:50:49.950
ein Re-Import durchgeführt.

00:50:50.410 --> 00:50:52.330
Und das ist möglich durch die Funktion

00:50:52.330 --> 00:50:54.310
aus Importlib. Da kann ich sagen,

00:50:54.450 --> 00:50:56.330
importiere diese spezifische Datei,

00:50:58.150 --> 00:50:58.550
auch wenn

00:50:58.550 --> 00:50:59.530
die schon mal importiert war,

00:51:00.650 --> 00:51:03.290
Und dann wird die importiert.

00:51:03.710 --> 00:51:04.970
Egal, ob die schon im Cache liegt oder nicht.

00:51:05.590 --> 00:51:05.910
Ja, cool.

00:51:06.030 --> 00:51:08.070
Ja, ich meine, der Entwicklungs-Server von Django,

00:51:08.150 --> 00:51:09.370
der kann sowas ja auch.

00:51:09.450 --> 00:51:10.630
Ja, aber der macht ja einen Neustart.

00:51:10.730 --> 00:51:11.910
Der macht tatsächlich einen Neustart, na ja.

00:51:12.470 --> 00:51:13.550
Der hat so einen Watcher-Prozess

00:51:13.550 --> 00:51:15.290
und dann schießt er einfach den Prozess ab

00:51:15.290 --> 00:51:16.070
und startet einmal neu.

00:51:16.150 --> 00:51:17.890
Ach so, ich weiß gar nicht, wie das, wie das,

00:51:18.050 --> 00:51:20.390
gut, das ist ja, oh mein Gott, das ist ja schrecklich.

00:51:21.190 --> 00:51:22.430
Ja, aber es hat auch Vorteile,

00:51:22.430 --> 00:51:25.030
weil dann halt alles auf Null zurück ist.

00:51:25.270 --> 00:51:26.110
Ja, ja, das, ja.

00:51:27.390 --> 00:51:28.470
Wie ist das denn bei Jupyter?

00:51:28.530 --> 00:51:29.070
Ist das ja auch so.

00:51:29.130 --> 00:51:31.110
da kann ich ja auch beim Import sagen,

00:51:31.290 --> 00:51:32.930
ob ich das jetzt möchte, dass ich das nochmal

00:51:32.930 --> 00:51:34.870
importieren will, wenn es sich ändert.

00:51:35.290 --> 00:51:35.730
Ja, dann mach so ein Reimport.

00:51:36.250 --> 00:51:38.490
Da gibt es eben diese Jupyter-Magic,

00:51:38.790 --> 00:51:40.690
die du sagen kannst und der benutzt tatsächlich

00:51:40.690 --> 00:51:41.690
Import-Lib und macht Reimport.

00:51:42.350 --> 00:51:43.230
Aha, okay.

00:51:45.610 --> 00:51:46.710
Neu starten wäre auch blöd.

00:51:46.850 --> 00:51:49.070
Ja, geht ja auch

00:51:49.070 --> 00:51:50.070
an der Stelle einfach gar nicht.

00:51:51.150 --> 00:51:53.050
Zum einen, weil der Prozess ja da

00:51:53.050 --> 00:51:55.010
läuft und zum anderen, weil

00:51:55.010 --> 00:51:56.790
du ja die anderen Zellen nicht kaputt machen willst.

00:51:56.910 --> 00:51:57.770
Du hast ja die Zellen immer noch.

00:51:58.530 --> 00:52:00.390
Ich hatte übrigens tatsächlich jetzt

00:52:00.390 --> 00:52:01.850
letzte,

00:52:02.290 --> 00:52:04.430
vorletzte, ne, letzte oder vorletzte, ne,

00:52:04.490 --> 00:52:06.390
letzte Woche, und ich erinnere mich schon nicht mehr dran,

00:52:06.690 --> 00:52:08.490
den Fall, wo ich tatsächlich Importlib

00:52:08.490 --> 00:52:10.810
gebraucht habe und habe halt die Importfunktion

00:52:10.810 --> 00:52:11.350
überschrieben.

00:52:12.670 --> 00:52:13.910
Was hast du damit gemacht?

00:52:14.870 --> 00:52:16.370
Ich habe einen Pull-Request

00:52:16.370 --> 00:52:17.570
bei Wagtail Media

00:52:17.570 --> 00:52:20.470
eingereicht, weil es nicht mit

00:52:20.470 --> 00:52:21.990
Wagtail 2.13 kompatibel war.

00:52:25.130 --> 00:52:25.610
Spannend.

00:52:25.610 --> 00:52:27.670
Ja, da gibt es Tests

00:52:27.670 --> 00:52:29.450
und das Problem ist jetzt,

00:52:29.730 --> 00:52:31.350
dass man jetzt in den, man möchte

00:52:31.350 --> 00:52:33.210
die Tests ja, also

00:52:33.210 --> 00:52:35.410
da ist dann, okay, ich fange einfach mal

00:52:35.410 --> 00:52:37.410
von der Seite an, es gibt im Code so Dinge wie

00:52:37.410 --> 00:52:39.430
probier das mal zu importieren,

00:52:39.630 --> 00:52:41.410
wenn es schief geht, mach was anderes,

00:52:41.630 --> 00:52:43.630
weil zum Beispiel diese Telepath

00:52:43.630 --> 00:52:45.330
Bibliothek gibt es erst ab Backtail

00:52:45.330 --> 00:52:46.610
2013. Okay.

00:52:47.790 --> 00:52:49.050
Und da sagt man halt, probier es zu importieren.

00:52:49.050 --> 00:52:51.350
Ja, auch für lokale, ich benutze es ganz häufig für lokale

00:52:51.350 --> 00:52:53.390
Settings, ja. Irgendwo eine local settings

00:52:53.390 --> 00:52:54.670
.py und dann macht man halt

00:52:54.670 --> 00:52:57.770
Try-Import-Local-Settings-to-Py

00:52:57.770 --> 00:52:58.870
und Accept-Parse.

00:53:00.910 --> 00:53:01.630
Genau, genau.

00:53:02.130 --> 00:53:03.310
Und jetzt möchten wir das aber testen.

00:53:03.370 --> 00:53:04.710
Jetzt möchten wir testen, dass wenn

00:53:04.710 --> 00:53:07.530
und es gibt da noch komplizierter

00:53:07.530 --> 00:53:09.730
wie gesagt, das habe ich jetzt wieder vergessen, blöderweise, ein bisschen komplizierter

00:53:09.730 --> 00:53:11.410
Logik, die davon abhängt, ob man es jetzt

00:53:11.410 --> 00:53:12.750
geschafft hat, das zu importieren oder nicht.

00:53:13.470 --> 00:53:15.350
Und jetzt, wie willst du das testen, ob jetzt wirklich der

00:53:15.350 --> 00:53:17.470
richtige Code ausgeführt wird, also der Code, der zum Beispiel

00:53:17.470 --> 00:53:19.330
dann nur so ein Dummy-Objekt

00:53:19.330 --> 00:53:21.470
anlegt. Wie willst du testen,

00:53:21.590 --> 00:53:23.270
ob das funktioniert hat, wenn du

00:53:23.270 --> 00:53:25.950
nicht dann noch eine andere Paketversion

00:53:25.950 --> 00:53:28.050
installieren willst, was du im Test auch nicht gut machen kannst.

00:53:28.570 --> 00:53:29.810
Ja, und dann habe ich da

00:53:29.810 --> 00:53:31.750
einfach quasi Importfunktionen

00:53:31.750 --> 00:53:33.850
überschrieben und dann in der Importfunktion gucke ich halt so,

00:53:34.190 --> 00:53:35.510
wird gerade versucht, das da zu importieren?

00:53:35.910 --> 00:53:37.030
Ja, wirklich? Gut.

00:53:37.550 --> 00:53:39.570
Race Exception, ja, und dann Race Import Error.

00:53:40.230 --> 00:53:41.590
Und dann kann man halt testen, okay,

00:53:41.710 --> 00:53:43.510
und ist jetzt wirklich das Dummy-Objekt? Ja oder nein?

00:53:43.890 --> 00:53:44.790
Und dann hat man einen Test dafür.

00:53:45.650 --> 00:53:46.790
Ja, aber...

00:53:46.790 --> 00:53:48.970
Das ist ja spannend, aber das ist auch ganz schön tief

00:53:48.970 --> 00:53:50.030
eingegriffen in die...

00:53:50.030 --> 00:53:51.810
Hat der Jochen auch schon aufgenommen?

00:53:52.510 --> 00:53:53.650
Ja, genau.

00:53:54.130 --> 00:53:55.450
Du musst jetzt aber suchen, in welcher Folge das war.

00:53:55.450 --> 00:53:56.510
Kannst du uns da einen Link geben, Jochen?

00:53:56.570 --> 00:53:57.870
Kann ich auch mal in die Schauenden folgen.

00:53:58.230 --> 00:53:58.710
Das ist ja cool.

00:53:59.650 --> 00:54:03.050
Ja, aber es kann ja noch alles dann passieren.

00:54:03.330 --> 00:54:04.790
Genau, das ist jetzt sozusagen,

00:54:04.970 --> 00:54:06.370
der Jochen hat jetzt hier schon die Brücke

00:54:06.370 --> 00:54:08.430
zu dem zweiten Anwendungsfall geschlagen,

00:54:08.530 --> 00:54:09.930
was dann eben hier aus diesem Artikel

00:54:09.930 --> 00:54:11.030
in der Diskussion rauskam.

00:54:11.510 --> 00:54:15.330
Man kann auch im Importsystem was anderes machen

00:54:15.330 --> 00:54:18.570
und der schöne Vorschlag, der da kam,

00:54:18.670 --> 00:54:19.970
beziehungsweise das schöne Beispiel,

00:54:19.970 --> 00:54:21.310
was da in dieser Diskussion kam,

00:54:21.990 --> 00:54:23.790
ist, dass man ja prinzipiell auch

00:54:23.790 --> 00:54:25.790
andere Sprachen integrieren könnte. Einfach Importsystem

00:54:25.790 --> 00:54:27.850
aufeinandersetzen. Das kann man auch machen,

00:54:27.910 --> 00:54:29.210
dann ist man in seiner eigenen Welt.

00:54:31.130 --> 00:54:31.910
Aber quasi

00:54:31.910 --> 00:54:33.250
das Gegenteil davon ist, wenn

00:54:33.250 --> 00:54:35.790
kein Python-Modul gefunden wird, dann kann man ja mal schauen, ob man

00:54:35.790 --> 00:54:37.790
irgendwas anderes kompilieren kann, was diesen Namen hat.

00:54:38.750 --> 00:54:39.030
Und

00:54:39.030 --> 00:54:41.570
wenn das kompilierbar ist und kompiliert, dann

00:54:41.570 --> 00:54:42.670
einfach das importieren.

00:54:43.650 --> 00:54:45.750
Und das hat wohl jemand geschrieben, dass jemand sich eben

00:54:45.750 --> 00:54:47.850
so Lisp-Dateien rein importieren kann,

00:54:47.850 --> 00:54:49.890
die live kompiliert werden,

00:54:49.970 --> 00:54:50.890
wenn man sie importiert.

00:54:51.990 --> 00:54:54.390
reichlich abgefahren, würde ich sagen

00:54:54.390 --> 00:54:56.170
und ich empfehle auch niemandem, diesen

00:54:56.170 --> 00:54:58.310
Weg zu gehen, aber es ist

00:54:58.310 --> 00:54:59.930
schön, dass es jemanden gibt, der das

00:54:59.930 --> 00:55:01.650
gemacht hat und dass es möglich ist.

00:55:03.670 --> 00:55:04.270
Ich wüsste

00:55:04.270 --> 00:55:06.230
jetzt tatsächlich keinen richtig sinnvollen

00:55:06.230 --> 00:55:07.410
Anwendungszweck davon, aber

00:55:07.410 --> 00:55:09.530
naja,

00:55:09.890 --> 00:55:12.230
irgendwann wird es

00:55:12.230 --> 00:55:13.410
einen Anwendungsfall geben.

00:55:13.530 --> 00:55:14.650
Ich habe gerade überlegt,

00:55:14.770 --> 00:55:18.090
wenn man das jetzt mit

00:55:18.090 --> 00:55:18.930
TypeScript macht,

00:55:19.370 --> 00:55:21.930
man möchte auf dem Backend und vorne den gleichen

00:55:21.930 --> 00:55:23.830
Code. Ja, und dann

00:55:23.830 --> 00:55:25.130
wird es noch mit dem

00:55:25.130 --> 00:55:27.510
JavaScript-to-Python-Compiler

00:55:27.510 --> 00:55:29.750
zu Python gemacht. Dann hat man noch

00:55:29.750 --> 00:55:31.450
einen Server, irgendwas, was WebAssembly kann.

00:55:32.750 --> 00:55:33.750
Man kann Python

00:55:33.750 --> 00:55:35.370
schreiben für Frontend. Und schon

00:55:35.370 --> 00:55:37.770
eigentlich, deine Dateien

00:55:37.770 --> 00:55:39.370
bestehen quasi nur noch aus Import-Statements.

00:55:39.510 --> 00:55:41.690
Alles wird mit

00:55:41.690 --> 00:55:43.690
Import-Statements gemacht.

00:55:43.790 --> 00:55:45.710
Ja, das ist so wie der Präprozessor.

00:55:45.770 --> 00:55:46.810
Der ist auch Turing-vollständig.

00:55:47.510 --> 00:55:48.390
Ja, tja.

00:55:50.570 --> 00:55:51.470
Da hat jemand

00:55:51.470 --> 00:55:53.490
super wieder sein. Vorhin haben wir noch

00:55:53.490 --> 00:55:55.150
drüber gesprochen, ob wir unser

00:55:55.150 --> 00:55:57.330
Telefon ausfalten wollen.

00:55:57.630 --> 00:55:59.230
Flugmodus gestellt, aber nicht

00:55:59.230 --> 00:55:59.610
mein Rechner.

00:56:01.030 --> 00:56:02.690
Auf meinem Telefon hat es auch nicht geklingelt, sondern

00:56:02.690 --> 00:56:05.510
mein Rechner kann halt auch dummerweise klingeln.

00:56:05.910 --> 00:56:07.370
Was kann denn noch alles schief gehen bei den

00:56:07.370 --> 00:56:09.330
Importen? Ja, eigentlich kann beim Importen alles

00:56:09.330 --> 00:56:10.630
schief gehen, oder? Das ist ja...

00:56:10.630 --> 00:56:13.390
Ja. Da steht irgendwas Komisches

00:56:13.390 --> 00:56:15.090
drin, also keine Binärcodes oder irgendein andere

00:56:15.090 --> 00:56:16.450
Zeichen, das er nicht lesen kann oder sowas.

00:56:17.430 --> 00:56:19.430
Ja, es können auch...

00:56:19.430 --> 00:56:21.350
Ich glaube, das Schwierigste an diesem Importsystem

00:56:21.350 --> 00:56:23.190
ist, dass es halt manchmal überraschend ist, ja, dass es

00:56:23.190 --> 00:56:25.270
einem Sachen versucht zu importieren,

00:56:25.530 --> 00:56:26.690
die man nicht gemeint hat.

00:56:28.150 --> 00:56:29.310
Weil die Reihenfolge im

00:56:29.310 --> 00:56:31.250
Path falsch ist oder weil da Module liegen,

00:56:31.330 --> 00:56:33.230
die man auch nicht kennt oder weil

00:56:33.230 --> 00:56:35.210
man versehentlich einen Namen verwendet hat, den es

00:56:35.210 --> 00:56:37.130
schon gibt. Also wenn man

00:56:37.130 --> 00:56:39.430
so eine Kette durchgeht, also man möchte jetzt A importieren

00:56:39.430 --> 00:56:41.230
und A möchte aber ja C, D, E,

00:56:41.310 --> 00:56:43.110
F, G und Y. Genau, sowas kann natürlich auch passieren,

00:56:43.210 --> 00:56:45.630
dann hast du zirkuläre Imports, das ist auch

00:56:45.630 --> 00:56:47.270
schlecht. Ja, aber das wäre ja von A

00:56:47.270 --> 00:56:48.990
von B und C und C von A.

00:56:49.430 --> 00:56:50.910
Ja, genau, und das hat man ja manchmal.

00:56:51.350 --> 00:56:53.430
Aber das war ein anderes Problem, als das, was ich gerade meinte.

00:56:53.530 --> 00:56:55.770
Ich meine, dass da so ganz, ganz, ganz viel Zeugs importiert ist.

00:56:55.850 --> 00:56:57.050
Also du könntest ja quasi eine Sache importieren,

00:56:57.110 --> 00:56:58.750
und der importiert alles andere, die ganze Standardbibliothek.

00:56:58.750 --> 00:57:01.070
Ja, klar. Im Prinzip machst du das ja so in deinem Skript.

00:57:01.930 --> 00:57:04.370
Genau, und das ist halt so relativ getarnt, was da passiert.

00:57:04.530 --> 00:57:06.090
Man macht relativ viel Magie schon.

00:57:06.970 --> 00:57:11.950
Und ja, also was halt die komplizierte Frage wäre,

00:57:12.050 --> 00:57:13.370
ob das das irgendwie dann doch langsam macht,

00:57:13.710 --> 00:57:15.170
wenn man irgendwie sowas raussucht und sagt,

00:57:15.250 --> 00:57:16.050
okay, beim ersten Mal schon.

00:57:16.470 --> 00:57:18.110
Das heißt, da kann der Starten relativ lange dauern

00:57:18.110 --> 00:57:19.730
und beim zweiten Mal dann vielleicht nicht.

00:57:20.590 --> 00:57:22.070
Aber es gab irgendwie so ein Problem,

00:57:22.210 --> 00:57:23.890
das irgendwer hatte, der das mal ausprobiert hat

00:57:23.890 --> 00:57:24.930
wegen den Imports.

00:57:26.030 --> 00:57:27.970
Ja, ja, ja. Also das Problem gibt es,

00:57:28.010 --> 00:57:29.550
wenn du halt irgendwie so auf die Richtung,

00:57:29.850 --> 00:57:31.870
weiß ich nicht, Millionen Zeilen Python

00:57:31.870 --> 00:57:33.850
oder so zugehst, dass eben dann, wenn das zum Beispiel

00:57:33.850 --> 00:57:35.610
im Entwicklungsserver, wenn der neu startet,

00:57:35.630 --> 00:57:37.250
wenn du so änderst irgendwas, dann startet der neu.

00:57:38.030 --> 00:57:38.950
Und dann dauert das halt eine Minute.

00:57:39.490 --> 00:57:42.090
Das ist halt schlecht. Das ist immer so richtig flüssig

00:57:42.090 --> 00:57:42.710
beim Entwickeln.

00:57:43.090 --> 00:57:45.410
Es hieß ja irgendwie so, wie an Google, aber ich glaube,

00:57:45.410 --> 00:57:46.790
das war bei Instagram das Problem oder so.

00:57:47.270 --> 00:57:49.070
Ja, bei Instagram gibt es auch bei

00:57:49.070 --> 00:57:51.650
Eventbrite gibt es das, glaube ich, auch.

00:57:52.110 --> 00:57:53.350
Die sind nicht so groß wie Google.

00:57:53.870 --> 00:57:54.850
Ja, aber die haben, glaube ich, auch irgendwie

00:57:54.850 --> 00:57:55.590
oder

00:57:55.590 --> 00:57:59.490
verwechsel ich das gerade? Nein, ich meine, es ist Eventbrite.

00:57:59.750 --> 00:58:01.730
Die haben auch ungefähr eine Million Zeilen Code und Instagram

00:58:01.730 --> 00:58:03.730
halt auch, vielleicht noch mehr, weiß nicht.

00:58:04.370 --> 00:58:04.650
Ja, okay.

00:58:05.290 --> 00:58:06.230
Aber das ist ja dann so,

00:58:06.490 --> 00:58:09.590
das Problem ist ja eigentlich, dass

00:58:09.590 --> 00:58:11.790
halt die Sachen erst so in Anführungszeichen

00:58:11.790 --> 00:58:13.610
kompiliert werden, wenn ich Import sage.

00:58:14.350 --> 00:58:15.650
Und deshalb haben andere Sprachen

00:58:15.650 --> 00:58:17.530
das nicht, weil die machen das halt einmal vorher.

00:58:18.030 --> 00:58:18.110
Ja.

00:58:19.070 --> 00:58:20.950
Aber so eine richtig gute Lösung, also ich meine, es gibt

00:58:20.950 --> 00:58:23.150
PyO-Dateien und PyC-Dateien,

00:58:24.210 --> 00:58:25.270
die sind ja wohl schneller.

00:58:26.330 --> 00:58:26.470
Ja.

00:58:27.850 --> 00:58:28.710
Oder könnte man

00:58:28.710 --> 00:58:30.430
sowas auch marscheln?

00:58:31.650 --> 00:58:33.250
Könnte man Imports durchführen

00:58:33.250 --> 00:58:34.970
und das dann, ja, im Prinzip schon, oder?

00:58:35.410 --> 00:58:37.190
Wahrscheinlich schon, ja. Einfach mal alles

00:58:37.190 --> 00:58:37.570
gepickelt.

00:58:39.910 --> 00:58:40.270
Tja.

00:58:41.270 --> 00:58:43.090
Ach, deswegen auch, weil der Pickel ist die Haube von dem Marschall.

00:58:43.090 --> 00:58:43.930
Ah, jetzt verstehe ich das auch.

00:58:44.990 --> 00:58:46.730
Ich dachte, Pickel ist so ein Einmachglas.

00:58:47.310 --> 00:58:48.990
Die Marschalls haben doch so eine Pickelhaube auf.

00:58:49.070 --> 00:58:50.790
Ja. Also dann passt

00:58:50.790 --> 00:58:51.530
es auf jeden Fall zusammen.

00:58:52.630 --> 00:58:54.730
Sorry, weigert mich.

00:58:55.310 --> 00:58:56.390
Das englische Wort Pickles heißt

00:58:56.390 --> 00:58:58.070
Eingemachtes. Ja, ja.

00:58:59.370 --> 00:59:01.050
Ich glaube, das ist die...

00:59:01.050 --> 00:59:02.690
Okay, aber zirkuläre Importe wollte ich

00:59:02.690 --> 00:59:04.250
nochmal... Ja, zirkuläre Importe sind auch

00:59:04.250 --> 00:59:06.410
eine schöne Sache. Also man kann ja sowas machen wie

00:59:06.410 --> 00:59:07.750
in Python Form A Import B und dann

00:59:07.750 --> 00:59:10.250
in B machen Form B Importe irgendwas

00:59:10.250 --> 00:59:12.030
oder Import A, Import B, Import D und so.

00:59:12.390 --> 00:59:14.390
Und das funktioniert einfach, aber erst wenn man

00:59:14.390 --> 00:59:15.430
es dann ausführt, dann nicht mehr.

00:59:16.070 --> 00:59:18.430
Weil er dann darauf zugreift und dann sagt, das kennt er noch

00:59:18.430 --> 00:59:20.010
nicht, weil es unvollständig ist.

00:59:20.190 --> 00:59:22.550
Es ist schon geladen oder es ist schon am Laden.

00:59:22.930 --> 00:59:24.270
Ja, genau. Also wenn ich

00:59:24.270 --> 00:59:26.610
zirkuläre

00:59:26.610 --> 00:59:28.270
Verweise habe, ja, vom A Import B

00:59:28.270 --> 00:59:29.410
und in B sage ich vom

00:59:29.410 --> 00:59:32.290
wenn ich Modul A und B habe

00:59:32.290 --> 00:59:34.350
und in A sage ich Import B und in B sage ich

00:59:34.350 --> 00:59:36.570
Import A, dann kann ich die beide nicht importieren,

00:59:36.650 --> 00:59:38.470
weil zu dem Zeitpunkt müsste ich sie beide gleichzeitig

00:59:38.470 --> 00:59:40.470
importieren und das geht

00:59:40.470 --> 00:59:42.470
nicht. Und da

00:59:42.470 --> 00:59:43.970
kann ich natürlich beliebig viele dazwischen schieben.

00:59:44.150 --> 00:59:46.110
Ich kann A, B, C, D, E, S.

00:59:46.470 --> 00:59:48.410
Solange dieser Kreis sich irgendwann schließt,

00:59:48.430 --> 00:59:49.990
ist schlecht.

00:59:51.070 --> 00:59:52.630
Also es fällt ja direkt auf. Ich glaube, wenn man

00:59:52.630 --> 00:59:54.410
drei hat, dann fällt es glaube ich nicht immer direkt auf.

00:59:54.850 --> 00:59:56.670
Wenn man vier oder fünf hat, dann fällt es erst

00:59:56.670 --> 00:59:58.830
recht. Also das siehst du

00:59:58.830 --> 01:00:00.570
dann beim Importieren. Und wie löst man das denn,

01:00:00.630 --> 01:00:02.230
wenn man erst so ein Problem hat? Ja,

01:00:03.590 --> 01:00:04.350
Laufzeitimport.

01:00:04.650 --> 01:00:06.250
Also lazy quasi. Ja.

01:00:06.350 --> 01:00:08.410
Das ist doch das, was man in

01:00:08.410 --> 01:00:10.230
so Salary-Tasks immer machen muss.

01:00:10.930 --> 01:00:12.970
Weil diese Tasks können von irgendwoher

01:00:12.970 --> 01:00:14.850
gestartet werden und die sollen dann irgendwas machen.

01:00:15.930 --> 01:00:16.990
Und die müssen

01:00:16.990 --> 01:00:18.930
ja auch irgendwie diese Modelle importieren, aber das Modell

01:00:18.930 --> 01:00:21.110
selber möchte. Also das ist so mein klassischer

01:00:21.110 --> 01:00:22.490
Anwendungsfall. Ich möchte Modell

01:00:22.490 --> 01:00:24.410
sagen, ich muss hier Werte

01:00:24.560 --> 01:00:27.020
nachberechnen, ich muss hier ein PDF erzeugen

01:00:27.020 --> 01:00:28.940
und das dauert

01:00:28.940 --> 01:00:30.660
lange und deshalb mache ich das in dem Task. Aber dieser

01:00:30.660 --> 01:00:32.640
Task soll ja dann wieder dieses ursprüngliche Modell

01:00:32.640 --> 01:00:34.680
speichern. Das heißt, ich kann in der

01:00:34.680 --> 01:00:36.620
Tasks-Datei nicht das Modell

01:00:36.620 --> 01:00:38.720
importieren, weil das Modell hat schon den Task

01:00:38.720 --> 01:00:40.660
importiert. Und deshalb

01:00:40.660 --> 01:00:42.440
ist das so ein Pattern, wenn man

01:00:42.440 --> 01:00:44.460
Celery-Tasks schreibt, dass diese

01:00:44.460 --> 01:00:46.680
Tasks zur Laufzeit alles

01:00:46.680 --> 01:00:48.380
importieren. Also in der Datei,

01:00:48.660 --> 01:00:49.620
in der Funktion

01:00:49.620 --> 01:00:51.740
dev-compute-pdf

01:00:51.740 --> 01:00:54.460
habe ich erst mal ein paar Importzeilen drin,

01:00:54.520 --> 01:00:56.540
Import from Models, Import irgendwas.

01:00:57.460 --> 01:00:58.580
Import PDF Generator.

01:00:59.620 --> 01:01:00.540
Und noch

01:01:00.540 --> 01:01:02.540
alles, was man da halt so importiert braucht. Und dann

01:01:02.540 --> 01:01:04.360
werden diese Imports erst

01:01:04.360 --> 01:01:06.420
ausgeführt, wenn die Funktion gestartet wird.

01:01:06.840 --> 01:01:08.620
Also von mir, von meinem geistigen Auge, die haben gerade so ein paar

01:01:08.620 --> 01:01:10.140
Tickets, die noch auf die To-Do-Liste müssen. Ja.

01:01:12.000 --> 01:01:12.400
Genau.

01:01:13.340 --> 01:01:14.520
Das bedeutet halt, dass

01:01:14.520 --> 01:01:16.660
dieser Import nicht ausgeführt wird, wenn die Datei

01:01:16.660 --> 01:01:17.180
geladen wird.

01:01:18.780 --> 01:01:20.560
Was eben der Fall wäre, wenn es oben in der

01:01:20.560 --> 01:01:22.520
Datei drinstehende. Sondern dieser Import

01:01:22.520 --> 01:01:24.420
wird erst ausgeführt, wenn die Funktion,

01:01:24.520 --> 01:01:26.540
da drin ist, gestartet wird. Weil quasi nur

01:01:26.540 --> 01:01:28.500
der Funktionsname geladen

01:01:28.500 --> 01:01:30.360
wird und das, was passieren soll quasi.

01:01:30.520 --> 01:01:32.360
Genau, richtig. Und wenn ich diese

01:01:32.360 --> 01:01:34.400
Funktion dann ausführe, dann wird dieses Import

01:01:34.400 --> 01:01:36.500
Statement ausgeführt. Und dann

01:01:36.500 --> 01:01:38.340
sind die anderen Sachen schon da und dann hat man quasi den

01:01:38.340 --> 01:01:40.440
Laser-Import, dann kann man das dann wieder machen, weil die sind

01:01:40.440 --> 01:01:42.460
ja schon dann. Das ist dann schon fertig, importiere diese Models,

01:01:42.540 --> 01:01:44.360
die sind schon im Cache, dann kann ich einfach in den Cache zeigen

01:01:44.360 --> 01:01:45.160
und sagen, hier, gib mir das.

01:01:46.700 --> 01:01:48.460
Bin also sozusagen aus diesem Prozess

01:01:48.460 --> 01:01:50.380
raus. Und das ist auch sowas, was es

01:01:50.380 --> 01:01:52.500
eben, was eben anders ist als in anderen Sprachen.

01:01:52.640 --> 01:01:54.460
Import ist ein Statement, was einen

01:01:54.460 --> 01:01:55.040
Effekt hat.

01:01:56.260 --> 01:01:58.080
In C, wenn ich in C sage, import

01:01:58.080 --> 01:02:00.600
header.h, dann hat es keinen Effekt,

01:02:01.000 --> 01:02:02.540
das ist kein Code, der da erzeugt

01:02:02.540 --> 01:02:04.480
wird. Also C.h ist immer

01:02:04.480 --> 01:02:05.880
Header, noch mal für alle Leute kein C.

01:02:06.400 --> 01:02:08.420
Genau, .h ist immer Header, das sind so die

01:02:08.420 --> 01:02:10.220
Definitionen, was es da, die

01:02:10.220 --> 01:02:12.520
Deklarationen, nicht die Definitionen, die Deklarationen,

01:02:12.520 --> 01:02:14.720
was es da gibt und die .c-Datei

01:02:14.720 --> 01:02:16.500
enthält dann die Definitionen

01:02:16.500 --> 01:02:17.300
normalerweise.

01:02:18.020 --> 01:02:20.540
Also header.h ist natürlich dann die Definition der Header.

01:02:21.060 --> 01:02:22.560
Die Definition, da müsste es dann

01:02:22.560 --> 01:02:24.600
eine Datei

01:02:24.600 --> 01:02:26.120
dazugeben, die heißt header.c

01:02:26.120 --> 01:02:27.240
und die dann halt,

01:02:27.440 --> 01:02:29.040
war nur ein Beispiel.

01:02:30.620 --> 01:02:32.860
Aber dieses Import-Statement

01:02:32.860 --> 01:02:34.740
in einem C, das wird vom Compiler

01:02:34.740 --> 01:02:36.280
ausgeführt. Das wird nicht zur Laufzeit

01:02:36.280 --> 01:02:38.400
ausgeführt. Und in Python ist das anders.

01:02:38.620 --> 01:02:40.000
Der Compiler, der macht das,

01:02:40.400 --> 01:02:42.300
der schneidet die einfach zusammen,

01:02:42.680 --> 01:02:44.640
alle zu einer großen Datei und dann liest der einfach von oben

01:02:44.640 --> 01:02:46.480
nach unten durch. Und dann gibt es noch den Linker,

01:02:46.560 --> 01:02:48.500
der dann dafür sorgt, dass diese Verweise alle an der

01:02:48.500 --> 01:02:50.120
korrekten Stelle, an die korrekte Stelle zeigen.

01:02:50.120 --> 01:02:51.920
Das ist so ein mehrstufiger Prozess und

01:02:52.400 --> 01:02:54.060
Es ist halt alles, bevor das Programm gestartet

01:02:54.060 --> 01:02:55.880
wird. Und in Python ist immer alles,

01:02:56.820 --> 01:02:57.460
nachdem

01:02:57.460 --> 01:02:59.940
das Programm gestartet wird. Und das ist halt hier

01:02:59.940 --> 01:03:02.040
genau das Problem. Wenn ich Import B sage

01:03:02.040 --> 01:03:03.920
und versuche

01:03:03.920 --> 01:03:05.840
aber schon was zu importieren oder versuche

01:03:05.840 --> 01:03:07.440
schon B zu importieren, dann

01:03:07.440 --> 01:03:09.660
geht es halt nicht, weil es

01:03:09.660 --> 01:03:11.860
dann eben so einen Kreis bildet, der nicht

01:03:11.860 --> 01:03:13.920
aufgelöst werden kann. Wenn ich das aber erst später

01:03:13.920 --> 01:03:15.980
im Programm sage, wenn ich irgendwelche Funktionen

01:03:15.980 --> 01:03:17.740
geladen habe, die dann

01:03:17.740 --> 01:03:19.880
später nochmal diese Module

01:03:19.880 --> 01:03:21.840
brauchen, ist egal, wo die herkommen,

01:03:21.920 --> 01:03:24.120
wenn die schon im Cache sind, einwandfrei.

01:03:24.520 --> 01:03:26.220
Okay, aber das widerspricht ja so ein bisschen dieser

01:03:26.220 --> 01:03:28.000
Philosophie, dass Importe immer ganz oben stehen.

01:03:28.100 --> 01:03:30.440
Ja, genau. Deshalb ist das hier so der

01:03:30.440 --> 01:03:31.820
Nachteil da dran.

01:03:32.180 --> 01:03:34.180
Ja, ich fühle mich da auch immer so ein bisschen schmutzig, aber

01:03:34.180 --> 01:03:36.380
ja, ich mache das auch so. Aber es ist halt das Pattern

01:03:36.380 --> 01:03:38.220
und das ist der beste Weg außenrum.

01:03:38.540 --> 01:03:40.100
Es gibt noch eine andere Möglichkeit,

01:03:40.700 --> 01:03:42.380
die ich auch

01:03:42.380 --> 01:03:44.260
niemandem empfehlen möchte. Es ist ein sehr schöner Hack,

01:03:44.260 --> 01:03:45.080
den ich mal gehört habe.

01:03:45.980 --> 01:03:48.280
Wenn ich jetzt zum Beispiel nur einen Task importieren

01:03:48.280 --> 01:03:49.920
möchte, dann sage ich, from Tasks, Import,

01:03:50.040 --> 01:03:50.460
Great PDF.

01:03:51.660 --> 01:03:53.960
Und der Import-Prozess führt

01:03:53.960 --> 01:03:56.180
tatsächlich nur so lange diesen Import

01:03:56.180 --> 01:03:58.060
aus, bis dieses Objekt vorhanden ist.

01:03:59.860 --> 01:04:02.040
Alles, was unterhalb dieses Objektes

01:04:02.040 --> 01:04:02.400
ist,

01:04:03.420 --> 01:04:04.840
wird nicht ausgeführt.

01:04:05.540 --> 01:04:07.660
Das heißt, wenn ich meine Import-Statements

01:04:07.660 --> 01:04:09.520
ans Ende einer Datei mache,

01:04:10.800 --> 01:04:14.100
dann kann ich zirkuläre Importe machen

01:04:14.100 --> 01:04:16.040
in bestimmten

01:04:16.840 --> 01:04:18.020
Situationen, dann geht das.

01:04:20.040 --> 01:04:24.140
Aber auch das, wie gesagt, ist keine Empfehlung.

01:04:24.320 --> 01:04:27.460
Es ist nur, Imports ans Ende der Datei schreiben

01:04:27.460 --> 01:04:29.680
ist schon generell schlecht, weil man sie dann nicht mehr sieht.

01:04:30.220 --> 01:04:32.700
Und es ist auch dann schlecht, wenn man dann zirkuläre Importe ...

01:04:32.700 --> 01:04:34.440
Das kann man dann wahrscheinlich auch noch ein bisschen verschachteln.

01:04:34.720 --> 01:04:38.680
Also alle Leute, die ein größeres Interesse an Job Security haben,

01:04:38.780 --> 01:04:40.400
jetzt bitte mal aufpassen mit Schreiben.

01:04:42.200 --> 01:04:43.880
Das kriegt man hinterher nie wieder auseinander.

01:04:44.120 --> 01:04:44.680
Ja, nee.

01:04:46.460 --> 01:04:48.900
Und wenn man dann noch Homoglyphen nimmt

01:04:48.900 --> 01:04:51.040
und die Dateien alle gleich ausschauen,

01:04:51.140 --> 01:04:52.960
dann hat man ganz gewonnen.

01:04:55.380 --> 01:04:57.020
Ja, das ist ein Hack,

01:04:57.240 --> 01:04:58.820
der die Interna missbraucht,

01:04:58.900 --> 01:05:00.940
würde ich nicht empfehlen, aber es ist schön, dass es das gibt.

01:05:03.300 --> 01:05:04.300
Ja, ist auch manchmal

01:05:04.300 --> 01:05:06.760
interessant zu wissen, warum

01:05:06.760 --> 01:05:08.780
irgendwas funktioniert, wo man denkt, das kann gar nicht funktionieren,

01:05:08.860 --> 01:05:09.660
aber es funktioniert ja dann doch.

01:05:11.820 --> 01:05:12.420
Ja, ja.

01:05:13.420 --> 01:05:14.820
Nicht so selten, wie es funktioniert,

01:05:14.900 --> 01:05:16.460
was nicht, was eigentlich funktionieren sollte,

01:05:16.460 --> 01:05:17.700
aber trotzdem auch.

01:05:18.780 --> 01:05:24.640
Ja, Imports haben wir, oder?

01:05:25.400 --> 01:05:27.320
Erklärt, oder fällt euch noch was ein?

01:05:28.280 --> 01:05:30.140
Bin mir sicher, dass da noch ganz viele Fragen kommen.

01:05:30.240 --> 01:05:31.960
Vor allem, wie funktionieren Imports in anderen Sprachen?

01:05:33.080 --> 01:05:33.660
Ja, andersrum.

01:05:34.680 --> 01:05:35.540
Das ist nicht so genau.

01:05:37.120 --> 01:05:39.660
Ich bin mir sicher, dass da ganz, ganz, ganz viele Fragen noch offen sind

01:05:39.660 --> 01:05:41.380
und dass da ganz, ganz, ganz viele Fragen noch kommen werden.

01:05:42.060 --> 01:05:43.440
Einfach mal so ein bisschen als Einstieg,

01:05:43.620 --> 01:05:47.680
weil ich meine auch, mir waren da viele Dinge nicht so richtig klar.

01:05:47.800 --> 01:05:49.500
jetzt, nachdem ich den Artikel zumindest teilweise

01:05:49.500 --> 01:05:51.680
so gelesen habe, dachte ich, ja, okay,

01:05:51.780 --> 01:05:53.580
da kann man schon coole Sachen mitmachen und

01:05:53.580 --> 01:05:55.500
vor allen Dingen kann man das auch, dass das

01:05:55.500 --> 01:05:57.660
eben, dass ein Modul auch nur einfach ein Objekt ist,

01:05:57.780 --> 01:05:59.500
das ist irgendwie die Eigenschaft, kann man ja eigentlich

01:05:59.500 --> 01:06:01.340
total gut ausnutzen, um damit irgendwie

01:06:01.340 --> 01:06:02.360
Dinge zu machen.

01:06:03.340 --> 01:06:05.680
Aber sollte man. Sollte man vielleicht nicht,

01:06:05.680 --> 01:06:07.560
aber, nein, ich meine gerade, also zum Beispiel

01:06:07.560 --> 01:06:09.720
ein tatsächliches Problem, wo ich

01:06:09.720 --> 01:06:11.640
halt auch schon so mit Paketen und

01:06:11.640 --> 01:06:13.800
Dingen rumgespielt habe, wo ich dachte so, oh, da gibt's

01:06:13.800 --> 01:06:15.460
irgendwie, gibt's da keine gute Lösung für,

01:06:16.100 --> 01:06:17.900
Aber es wäre schön, eine zu haben.

01:06:18.140 --> 01:06:19.360
Oder ich weiß nicht, vielleicht kennst du eine.

01:06:19.800 --> 01:06:22.320
Im Machine Learning-Bereich, wenn man da Modelle hat,

01:06:22.400 --> 01:06:23.660
man trainiert die Modelle jetzt aber nicht.

01:06:24.100 --> 01:06:25.600
Also man hat normalerweise ein Produktionssystem,

01:06:25.700 --> 01:06:27.380
was irgendwie dann Dinge tut,

01:06:27.480 --> 01:06:30.720
so mit echten Usern und echten Daten und so.

01:06:31.780 --> 01:06:34.100
Aber da entwickelt man ja nicht

01:06:34.100 --> 01:06:35.440
und man trainiert ja auch nicht die Modelle,

01:06:35.600 --> 01:06:36.900
sondern Modelle trainierst du dann meistens

01:06:36.900 --> 01:06:38.500
irgendwie in einem Jupyter-Notebook oder so.

01:06:39.760 --> 01:06:40.600
Jetzt hast du da dein Modell

01:06:40.600 --> 01:06:43.000
und jetzt willst du das irgendwie

01:06:43.000 --> 01:06:45.160
aber in deine Produktionsumgebung integrieren.

01:06:46.100 --> 01:06:48.080
wie machst du das denn? Jetzt kannst du ja natürlich jedes Mal, wenn du

01:06:48.080 --> 01:06:50.080
irgendwie dein Modell trainiert hast, aber das sind ja oft Dinge,

01:06:50.140 --> 01:06:52.400
die dann auch periodisch passieren und automatisch,

01:06:52.940 --> 01:06:54.180
kannst du ein neues Paket bauen

01:06:54.180 --> 01:06:56.020
und das dann releasen. Aber

01:06:56.020 --> 01:06:57.620
dieser Deployment-Prozess ist halt

01:06:57.620 --> 01:06:58.800
ziemlich invasiv.

01:07:00.020 --> 01:07:02.180
Vielleicht willst du das nicht regelmäßig

01:07:02.180 --> 01:07:04.080
oder auch nicht automatisch machen, weil

01:07:04.080 --> 01:07:06.080
du brauchst ja Berechtigungen auf irgendwelchen Systemen und

01:07:06.080 --> 01:07:08.080
keine Ahnung. Gut, kannst du das natürlich auch

01:07:08.080 --> 01:07:10.200
Deployment automatisieren, was halt so ein bisschen

01:07:10.200 --> 01:07:12.020
höhe ist. Und

01:07:12.020 --> 01:07:14.260
du hast dann ganz, ganz viele Paketversionen

01:07:14.260 --> 01:07:16.140
auch. Und es ist halt viel,

01:07:16.980 --> 01:07:18.220
diese Modelle sind halt teilweise sehr

01:07:18.220 --> 01:07:18.620
riesig.

01:07:20.220 --> 01:07:21.980
Also irgendwie ist das nicht so richtig schön.

01:07:22.340 --> 01:07:24.080
Und das ist halt die Frage, wie macht man das

01:07:24.080 --> 01:07:26.120
eigentlich ordentlich? Und du hast das Problem, wenn man jetzt Sachen

01:07:26.120 --> 01:07:27.300
pickelt zum Beispiel auch,

01:07:28.160 --> 01:07:29.920
dann ist das

01:07:29.920 --> 01:07:31.840
von dem Python-Interpreter

01:07:31.840 --> 01:07:34.300
abhängig und so.

01:07:34.780 --> 01:07:35.780
Und der ist möglicherweise

01:07:35.780 --> 01:07:38.260
in diesem Jupyter-Notebook-Umfeld,

01:07:38.340 --> 01:07:40.000
wo jetzt die Data Scientists irgendwelche Modelle trainieren,

01:07:40.080 --> 01:07:42.160
halt auch wieder anders, aus speziellen

01:07:42.160 --> 01:07:43.860
Gründen anders als in

01:07:43.860 --> 01:07:45.860
Produktionsumgebungen, wo dann die

01:07:45.860 --> 01:07:48.060
Und Pickel kann ja selbst auch Imports

01:07:48.060 --> 01:07:49.120
durchführen. Ja.

01:07:49.700 --> 01:07:52.040
Das ist auch... Pickel muss man ein bisschen aufpassen

01:07:52.040 --> 01:07:53.860
wenn man Versionen nimmt oder so, also Sachen

01:07:53.860 --> 01:07:55.640
Pickelt und dann Python-Versionen weitergeht,

01:07:56.060 --> 01:07:57.640
das geht öfter mal kaputt, das heißt

01:07:57.640 --> 01:07:59.780
das ist nicht mehr so einfach dann... Ja, beziehungsweise auch

01:07:59.780 --> 01:08:01.500
wenn du andere Imports hast oder andere Versionen,

01:08:02.280 --> 01:08:03.800
Pickel importiert halt die Sachen, die es braucht

01:08:03.800 --> 01:08:04.920
und ja.

01:08:06.380 --> 01:08:07.140
Ja, und

01:08:07.140 --> 01:08:09.680
also das ist, das kann schon, also

01:08:09.680 --> 01:08:11.640
da gibt es diverse Fallstricke und

01:08:11.640 --> 01:08:13.840
der Weg, den ich dann irgendwann gegangen bin, ist halt dynamisch

01:08:13.840 --> 01:08:15.160
Conda-Pakete zu bauen

01:08:15.160 --> 01:08:17.860
und weil das mit Conda relativ leicht ging,

01:08:17.980 --> 01:08:19.780
aber das war, da kann, ich weiß nicht, ob es da

01:08:19.780 --> 01:08:21.920
Importlib, doch, Importlib gab es glaube ich auch schon, ich wusste

01:08:21.920 --> 01:08:23.460
aber nicht so viel davon, ich weiß nicht genau

01:08:23.460 --> 01:08:25.880
und die habe ich dann halt sozusagen

01:08:25.880 --> 01:08:28.300
als Django-Modelle

01:08:28.300 --> 01:08:29.860
irgendwie als Files irgendwo hingelegt und

01:08:29.860 --> 01:08:31.680
dann diese Pakete importiert

01:08:31.680 --> 01:08:33.720
und dann konnte man einfach einfach sozusagen sich

01:08:33.720 --> 01:08:35.900
konnte man in einem Jupyter-Notepunkt, wenn man ein Modell

01:08:35.900 --> 01:08:37.740
fertig trainiert hatte, konnte man sagen, deploy mir dieses

01:08:37.740 --> 01:08:39.520
Modell irgendwie und dann tauchte das halt

01:08:39.520 --> 01:08:41.700
auf und wenn man es ausgewählt hat, wurde es halt

01:08:41.700 --> 01:08:43.760
importiert und zwar einfach aus

01:08:43.760 --> 01:08:45.360
Aus der Datenbank importiert.

01:08:46.000 --> 01:08:47.560
Aus der Datenbank, beziehungsweise nicht aus der Datenbank,

01:08:47.700 --> 01:08:49.460
sondern aus der Datenbank plus irgendwie,

01:08:50.160 --> 01:08:51.380
naja, nicht in dem File-System, sondern

01:08:51.380 --> 01:08:52.840
in der File-System-Abstraktion,

01:08:53.660 --> 01:08:55.100
dem File-Storage,

01:08:55.380 --> 01:08:56.660
Django-Storage ist halt irgendwie.

01:08:57.520 --> 01:08:59.620
Und das geht

01:08:59.620 --> 01:09:01.560
wahrscheinlich auch ohne Conda, nehme ich mal an,

01:09:01.760 --> 01:09:03.140
so, wenn ich das jetzt mir so überlege,

01:09:03.380 --> 01:09:05.420
und wahrscheinlich geht das auch noch

01:09:05.420 --> 01:09:07.480
eleganter, als wie ich das damals gemacht habe.

01:09:08.320 --> 01:09:09.500
Ja, aber also jetzt mal

01:09:09.500 --> 01:09:09.780
die

01:09:09.780 --> 01:09:13.500
Diskussionsfrage, warum nicht wirklich

01:09:13.500 --> 01:09:15.000
aus der Datenbank importieren. Im Prinzip

01:09:15.000 --> 01:09:17.260
sind es ja nur irgendwelche Daten, kannst du ja als

01:09:17.260 --> 01:09:19.320
String da reinlegen und kannst sagen, importiere mir dieses

01:09:19.320 --> 01:09:21.080
Modell, kannst du ein Reimport machen und das

01:09:21.080 --> 01:09:23.220
also, dann wirst du vermutlich noch so

01:09:23.220 --> 01:09:24.120
einen Proxy-Pattern brauchen.

01:09:25.200 --> 01:09:27.140
Ja, also das Ding für Conda

01:09:27.140 --> 01:09:29.220
war dann halt tatsächlich irgendwie

01:09:29.220 --> 01:09:30.900
was ist, wenn ich jetzt irgendeine spezielle

01:09:30.900 --> 01:09:33.120
Abhängigkeit habe in

01:09:33.120 --> 01:09:35.160
meinem Modell, also ich benutze jetzt irgendeine neue

01:09:35.160 --> 01:09:37.480
fancy Maschine in der Bibliothek,

01:09:37.480 --> 01:09:39.540
die ich jetzt auf dem Produktionssystem

01:09:39.540 --> 01:09:41.420
jetzt aber noch nicht habe. Ja, okay, dann

01:09:41.420 --> 01:09:43.380
stößt das ab und... Genau, und

01:09:43.380 --> 01:09:45.280
dann ist halt kaputt.

01:09:45.900 --> 01:09:47.400
Wie kriege ich das da mit rein?

01:09:47.760 --> 01:09:49.420
Und zwar ohne, dass ich, ja, und das

01:09:49.420 --> 01:09:51.140
war, über Conda ging das, aber.

01:09:51.340 --> 01:09:53.520
Ja, okay. Das ist natürlich

01:09:53.520 --> 01:09:55.460
schwierig, ja, vor allem, wenn du dann Sachen installieren musst,

01:09:55.560 --> 01:09:57.420
die du eigentlich, was du an der Stelle

01:09:57.420 --> 01:09:59.400
eigentlich nicht willst. Wobei, also

01:09:59.400 --> 01:10:01.460
ich meine, PIP gibt es auch als Bibliothek, da kannst du

01:10:01.460 --> 01:10:02.420
auch PIP aufrufen,

01:10:02.500 --> 01:10:04.660
von Python heraus.

01:10:06.540 --> 01:10:06.680
Also,

01:10:07.080 --> 01:10:09.560
was ich für meine

01:10:09.560 --> 01:10:11.660
interaktive

01:10:11.660 --> 01:10:13.760
Programmieren-Sache gemacht habe, ist eben so ein

01:10:13.760 --> 01:10:14.520
Proxy-Pattern.

01:10:15.020 --> 01:10:18.020
Dass du quasi eine Schicht dazwischen hast.

01:10:18.480 --> 01:10:19.780
Weil du

01:10:19.780 --> 01:10:21.720
möchtest ja an der Stelle, wenn du es neu

01:10:21.720 --> 01:10:23.700
importierst, musst du halt auch ganz viele Instanzen

01:10:23.700 --> 01:10:24.740
ersetzen. Eigentlich.

01:10:25.720 --> 01:10:27.680
Und das ist schwierig, weil die hast du oft nicht

01:10:27.680 --> 01:10:29.780
selber in der Hand oder da kommst du oft einfach gar nicht dran.

01:10:30.000 --> 01:10:31.680
Also Instanzen, das heißt, du musst die laden mit dem

01:10:31.680 --> 01:10:33.500
neuen Kontext der neuen Importe. Genau.

01:10:33.500 --> 01:10:35.780
Weil du den neuen Code hast und

01:10:35.780 --> 01:10:37.040
eigentlich müsstest du jetzt die Instanzen...

01:10:37.040 --> 01:10:39.600
Du musst aber quasi ja alle Transaktionen, die du auf der einen Instanz

01:10:39.600 --> 01:10:41.620
hast du gemacht, hast du wieder nachvollziehen, weil du den State

01:10:41.620 --> 01:10:43.400
ja quasi wiederherstellen musstest. Genau, also genau,

01:10:43.520 --> 01:10:45.760
das ist die eine Sache, du müsstest den State quasi wiederherstellen

01:10:45.760 --> 01:10:47.660
und die andere Sache ist, du müsstest den Code ersetzen,

01:10:47.780 --> 01:10:49.740
weil ich habe jetzt hier halt ein m.x

01:10:49.740 --> 01:10:51.380
und ich möchte aber ein m.x2 haben.

01:10:51.380 --> 01:10:53.160
Aber der State kann jetzt ganz anders sein, weil du hast jetzt nur m.

01:10:53.160 --> 01:10:55.440
Ja, genau, kann sein. Und dafür gibt es

01:10:55.440 --> 01:10:57.860
einen Pattern, das heißt Proxy-Pattern,

01:10:57.940 --> 01:10:59.480
wo du quasi ein Interface definierst,

01:10:59.560 --> 01:11:00.480
was da alles drin ist.

01:11:01.100 --> 01:11:02.720
Was ist denn ein Interface? Also ja, also

01:11:02.720 --> 01:11:05.340
du definierst quasi,

01:11:05.440 --> 01:11:07.460
was ein Objekt kann. Also ein Typ.

01:11:07.860 --> 01:11:09.560
Und die eigentliche Umsetzung

01:11:09.560 --> 01:11:11.360
ist aber quasi eine Klasse dahinter.

01:11:11.700 --> 01:11:13.240
Du definierst quasi den Typ und dann...

01:11:13.240 --> 01:11:15.600
Dieser Proxy macht nichts anderes, als diese Aufrufe

01:11:15.600 --> 01:11:16.080
weitergeben.

01:11:17.420 --> 01:11:19.300
Und dann kannst du nämlich dem Proxy sagen,

01:11:19.420 --> 01:11:21.620
ersetz mal deinen Background,

01:11:21.860 --> 01:11:23.320
ersetz mal deinen Hintergrund, den Code,

01:11:24.260 --> 01:11:25.800
ohne den Proxy

01:11:25.800 --> 01:11:27.560
selbst anfassen zu müssen, den du halt oft

01:11:27.560 --> 01:11:29.440
nicht rauskriegst, weil der in irgendwelchen Sachen

01:11:29.440 --> 01:11:29.880
drin hängt.

01:11:31.760 --> 01:11:33.360
Ich könnte mir durchaus vorstellen, dass das

01:11:33.360 --> 01:11:35.460
mit so Machine Learning Modellen auch funktionieren

01:11:35.460 --> 01:11:36.740
könnte, dass du halt einen Proxy hast,

01:11:37.180 --> 01:11:39.420
der dieses Modell weg abstrahiert und der

01:11:39.420 --> 01:11:41.460
kann die Sachen irgendwoher wiederladen,

01:11:41.540 --> 01:11:43.220
ob das jetzt aus der Datenbank ist oder aus

01:11:43.220 --> 01:11:45.340
dem Dateisystem oder sonst woher.

01:11:48.080 --> 01:11:49.460
Einfach, dass du eine Trennungsschicht

01:11:49.460 --> 01:11:51.400
drin hast. Ja, das ist

01:11:51.400 --> 01:11:53.260
wahrscheinlich auch der richtige Weg.

01:11:53.980 --> 01:11:55.280
Das wäre der richtige Weg.

01:11:55.860 --> 01:11:56.140
Ja gut,

01:11:57.140 --> 01:11:59.420
man weiß das ja oft zu dem Zeitpunkt nicht so richtig.

01:11:59.920 --> 01:12:01.840
Es ist einiges an Verwaltungsaufwand,

01:12:02.140 --> 01:12:03.260
so ein Proxy richtig zu machen

01:12:03.260 --> 01:12:05.580
und das geht in manchen Sprachen

01:12:05.580 --> 01:12:07.420
einfacher. Ein Interface

01:12:07.420 --> 01:12:09.260
definieren geht in Java ganz einfach, weil es

01:12:09.260 --> 01:12:11.560
gibt es da halt. In Python ist es halt

01:12:11.560 --> 01:12:13.760
nur eine Klasse, die lauter Not-Implemented-Errors

01:12:13.760 --> 01:12:14.000
hat.

01:12:16.360 --> 01:12:17.660
Ja, aber ungefähr so, ja.

01:12:18.880 --> 01:12:19.080
Ja.

01:12:19.980 --> 01:12:21.540
Achso, gibt es zu diesem Projekt

01:12:21.540 --> 01:12:23.640
eigentlich auch schon einen Link

01:12:23.640 --> 01:12:25.480
oder sowas? Nee, demnächst.

01:12:26.500 --> 01:12:27.480
Wird nachgereicht.

01:12:27.580 --> 01:12:29.060
Ich liefere das nach. Okay.

01:12:29.220 --> 01:12:31.460
Und jetzt habe ich es öffentlich gesagt, jetzt muss ich es auch wirklich machen.

01:12:31.460 --> 01:12:32.960
Das ist immer gut. Sehr schön.

01:12:33.260 --> 01:12:35.360
Ich hatte ja, vielleicht rede ich mich ja

01:12:35.360 --> 01:12:37.380
gegenüber mir selbst, kann ich mich

01:12:37.380 --> 01:12:39.460
immer sehr leicht rausreden, aber wenn ich es jetzt schon gesagt habe.

01:12:39.460 --> 01:12:41.100
Ja, gib mal auf jeden Fall deine Bucketlist, dann

01:12:41.100 --> 01:12:43.400
erwähnen wir es mal öffentlich. Ja, gut, das ist gut.

01:12:45.440 --> 01:12:45.820
Ja, also

01:12:45.820 --> 01:12:47.500
interessant, was man aus so einem Blogartikel noch alles

01:12:47.500 --> 01:12:49.400
machen kann. Also wir hatten ja, glaube ich, ja vorher, bevor wir einen Blog

01:12:49.400 --> 01:12:51.180
gefunden hatten, irgendwie, und dann war ja irgendwie

01:12:51.180 --> 01:12:53.340
ergänzte Information. In demselben Blog habe ich

01:12:53.340 --> 01:12:55.260
noch so ein paar andere Sachen entdeckt, die wir auch vorhaben,

01:12:55.420 --> 01:12:57.420
sowas wie Datentypen sprechen und wie das implementiert

01:12:57.420 --> 01:12:59.540
ist und wie halt das Python-Objekt-System

01:12:59.540 --> 01:13:01.360
funktioniert oder die einzelnen Dinge oder

01:13:01.360 --> 01:13:03.420
der C-Python-Compiler,

01:13:03.560 --> 01:13:05.400
wie das überhaupt geht. Und da müssen wir auf jeden Fall

01:13:05.400 --> 01:13:07.400
auch mal drüber sprechen, aber schaut doch schon mal in diesen

01:13:07.400 --> 01:13:09.460
Bock rein, 10.000 Meters, komm, das fand ich wirklich interessant.

01:13:09.500 --> 01:13:10.760
Ja, da waren einige gute Sachen dabei.

01:13:10.760 --> 01:13:12.800
Ja, ziemlich nett und relativ aktuell.

01:13:13.400 --> 01:13:14.480
Ja, ich hab mir auch mal dieses

01:13:14.480 --> 01:13:16.340
Sea Python Internals Buch

01:13:16.340 --> 01:13:17.280
besorgt.

01:13:19.740 --> 01:13:20.060
Ja,

01:13:20.660 --> 01:13:22.460
mal schauen,

01:13:22.640 --> 01:13:23.880
vielleicht kann man da ja auch noch ein bisschen was rausholen.

01:13:23.960 --> 01:13:26.580
Ja, das werden wir auf jeden Fall, also vielleicht verpusten wir tatsächlich so

01:13:26.580 --> 01:13:27.560
jeden dieser Bock-Posts, also

01:13:27.560 --> 01:13:30.640
wir lesen die einfach vor.

01:13:30.840 --> 01:13:31.560
Wir lesen die einfach vor.

01:13:32.760 --> 01:13:34.660
Nein, das ist wirklich toll und ich glaube, das ist viel, was

01:13:34.660 --> 01:13:36.840
auch Hörer von uns gerne interessiert und wissen wollen,

01:13:36.940 --> 01:13:38.880
was da irgendwie so passiert, dass man so ein bisschen drüber redet, weil

01:13:38.880 --> 01:13:40.980
das machen wir ja, so ein bisschen erklären, wie Python

01:13:40.980 --> 01:13:42.260
so als Sprache und

01:13:42.260 --> 01:13:43.680
so und warum.

01:13:44.060 --> 01:13:46.660
Ja, spannend.

01:13:47.120 --> 01:13:48.800
Ja, super. Ich glaube, wir haben

01:13:48.800 --> 01:13:50.140
über Impulse gar nicht mehr so viel zu sagen.

01:13:50.940 --> 01:13:52.740
Ich habe gehört, Johannes hat sich extra einen Pick der Woche überlegt.

01:13:52.880 --> 01:13:53.580
Ich habe mir tatsächlich,

01:13:53.860 --> 01:13:56.440
ich habe einen Pick und zwar GitHub

01:13:56.440 --> 01:13:57.120
Octo.

01:13:59.780 --> 01:14:00.760
Das ist eine

01:14:00.760 --> 01:14:02.660
Anwendung, die GitHub geschrieben hat,

01:14:03.580 --> 01:14:04.300
mit der man

01:14:04.300 --> 01:14:07.100
Repositories visualisieren

01:14:07.100 --> 01:14:08.900
kann. Also die interne Struktur

01:14:08.900 --> 01:14:10.780
des Codes in einem Repository.

01:14:12.720 --> 01:14:13.800
Der Hintergrund ist,

01:14:14.780 --> 01:14:16.540
du kommst in ein neues Projekt rein und

01:14:16.540 --> 01:14:18.480
da sind jetzt eine Million Zeilen

01:14:18.480 --> 01:14:20.800
Python-Code drin und deine erste

01:14:20.800 --> 01:14:22.680
Aufgabe ist, mach mal hier eine

01:14:22.680 --> 01:14:23.480
Log-Ausgabe rein.

01:14:27.080 --> 01:14:29.080
Es ist sehr schwer, sich da zurechtzufinden

01:14:29.080 --> 01:14:30.320
und es ist auch sehr schwer,

01:14:30.660 --> 01:14:32.340
Sachen zu finden in Projekten,

01:14:32.880 --> 01:14:34.500
wenn man sie nicht sehr genau kennt.

01:14:35.060 --> 01:14:36.780
Und da ist eben GitHub-Octo, das macht hier

01:14:36.780 --> 01:14:38.980
so ein paar sehr schöne Grafen,

01:14:39.040 --> 01:14:40.080
das zeigt quasi grafisch,

01:14:40.260 --> 01:14:42.400
ich kann es jetzt mal ins Bild halten hier,

01:14:43.440 --> 01:14:44.520
zeigt quasi grafisch

01:14:44.520 --> 01:14:46.660
die Abhängigkeiten zwischen den verschiedenen

01:14:46.660 --> 01:14:48.780
Dateien, wo die liegen und

01:14:48.780 --> 01:14:50.260
wer sich importiert und wie die

01:14:50.260 --> 01:14:52.780
aufeinander aufbauen und dann kann man eben sehr schnell

01:14:52.780 --> 01:14:53.960
da so einen Überblick bekommen,

01:14:54.580 --> 01:14:56.560
darüber, was mit was interagiert und was

01:14:56.560 --> 01:14:58.620
wohin gehört. Also schöne

01:14:58.620 --> 01:15:00.400
Kreisbeispiele hier.

01:15:00.740 --> 01:15:02.580
Wundervoll, das sieht ja richtig kreativ aus.

01:15:02.580 --> 01:15:04.220
Es sieht richtig schön aus.

01:15:04.400 --> 01:15:06.000
Zum Ausdruck an die Wand hängen, also als Kunst jetzt.

01:15:06.480 --> 01:15:08.820
Ja, zum einen das und zum anderen auch funktionale

01:15:08.820 --> 01:15:10.660
Kunst, wo man eben nachsehen kann,

01:15:10.800 --> 01:15:12.360
von wo nach wo man hin

01:15:12.360 --> 01:15:14.580
navigieren muss. Und auch

01:15:14.580 --> 01:15:16.620
interessant, weil es eben so

01:15:16.620 --> 01:15:18.660
auf eine gewisse Art und Weise die Architektur

01:15:18.660 --> 01:15:19.900
einer Software widerspiegelt,

01:15:20.580 --> 01:15:22.660
die ja sehr unterschiedlich sein kann. Also wenn man sich

01:15:22.660 --> 01:15:24.820
hier diese Screenshots anschaut, die sind ja zum Teil sehr unterschiedlich.

01:15:24.920 --> 01:15:26.320
Manche sind halt sehr flache Hierarchien.

01:15:26.320 --> 01:15:27.080
Die Screenshots werden wir auch nicken.

01:15:27.320 --> 01:15:28.600
Sehr breit, selbstverständlich.

01:15:30.080 --> 01:15:32.040
Das sind sehr gut aufgeteilt, das sieht man vielleicht auch so ein bisschen

01:15:32.040 --> 01:15:34.040
in Style, das ist ja ganz schön. Genau, genau, also

01:15:34.040 --> 01:15:36.020
es ist wirklich einfach eine Einsicht, die man

01:15:36.020 --> 01:15:37.500
sonst nur sehr schwer kriegen kann

01:15:37.500 --> 01:15:39.360
oder auch hier, also hier gibt es eins.

01:15:39.660 --> 01:15:41.820
Den musst du direkt mal in die Gruppe teilen. Ja, selbstverständlich.

01:15:43.860 --> 01:15:45.820
Wo man eben sieht, dass jedes Paket quasi

01:15:45.820 --> 01:15:47.860
gleich ist und jedes Paket hat auch so eine Testpunkt-Pi

01:15:47.860 --> 01:15:49.780
drin und das sind eben halt diese grünen Punkte hier

01:15:49.780 --> 01:15:51.620
und man sieht, okay, jedes Paket hat eins oder

01:15:51.620 --> 01:15:53.900
in einem anderen Projekt sind die grünen Punkte

01:15:53.900 --> 01:15:55.800
halt alle in einem großen Modul drin und

01:15:55.800 --> 01:15:57.820
man sieht, okay, die sind nebendran,

01:15:57.940 --> 01:15:59.940
die sind offenbar nicht integriert. Also es gibt

01:15:59.940 --> 01:16:01.840
einfach sehr schnell einen Überblick über die

01:16:01.840 --> 01:16:03.760
Struktur eines Projektes, was so

01:16:03.760 --> 01:16:05.280
an sich nicht so einfach

01:16:05.280 --> 01:16:06.720
zu finden ist.

01:16:07.960 --> 01:16:09.220
Das ist mein Pick für diese Woche.

01:16:09.740 --> 01:16:11.520
Ich habe auch einen Pick. Ich würde picken

01:16:11.520 --> 01:16:12.200
Oh My Git.

01:16:13.240 --> 01:16:15.740
Das ist ein Spiel, wenn man Git lernen will.

01:16:15.920 --> 01:16:17.320
Oh My Git? Ja, Oh My Git.

01:16:18.320 --> 01:16:19.760
Ich weiß gar nicht, in was das geschrieben wurde.

01:16:20.620 --> 01:16:21.500
Aber man kann es halt

01:16:21.500 --> 01:16:23.580
mit Git spielen, mit so Karten und lernt so ein bisschen

01:16:23.580 --> 01:16:25.680
über Git. Also natürlich auch so Beginner-Level und so,

01:16:25.740 --> 01:16:27.740
aber das ist halt relativ spannend, wenn man so ein bisschen

01:16:27.740 --> 01:16:28.800
Advanced-Git noch machen will.

01:16:29.340 --> 01:16:31.380
also, weiß nicht, jetzt ein Rebase, Interactive

01:16:31.380 --> 01:16:33.260
und dann irgendwie gucken will, dass man irgendwelche Commits

01:16:33.260 --> 01:16:35.300
stasht, dass dann irgendwie dann doch irgendwie die Message

01:16:35.300 --> 01:16:37.260
ändern und was man da nicht so alles

01:16:37.260 --> 01:16:39.120
machen kann, so ein bisschen zu verstehen, was das überhaupt

01:16:39.120 --> 01:16:41.400
ist. Cool, hört sich auch spannend an.

01:16:41.480 --> 01:16:42.620
Sehr nice, ja, also Gamification

01:16:42.620 --> 01:16:45.380
mit Git halt als kleines Spielchen,

01:16:45.420 --> 01:16:47.340
das ist schon irgendwie cool. Gitification.

01:16:47.880 --> 01:16:49.140
Ja, man sieht halt auch, wenn man das ein bisschen

01:16:49.140 --> 01:16:51.220
visualisiert und man kann da so Sachen klicken und das ist

01:16:51.220 --> 01:16:53.300
irgendwie ganz nett, also weil, ich meine, so Branches oder so,

01:16:53.380 --> 01:16:55.240
jemand, der so ein bisschen programmiert oder hat das

01:16:55.240 --> 01:16:57.160
ja irgendwann schon mal gesehen oder viele Leute haben

01:16:57.160 --> 01:16:59.280
halt dann Git nur zum Pushen oder Pullen verwendet

01:16:59.280 --> 01:17:01.100
irgendwann, dass man so ein bisschen, man kann echt

01:17:01.100 --> 01:17:02.660
tolle Sachen mitmachen, also spannende Sachen und

01:17:02.660 --> 01:17:05.020
ja, deswegen kann ich es

01:17:05.020 --> 01:17:07.060
interessant, um so ein bisschen Advanced dann noch zu machen.

01:17:07.300 --> 01:17:08.980
Und geht ja auch in die gleiche Richtung, ist ja spannend.

01:17:09.300 --> 01:17:10.920
Ja. Ähnliche Picks haben die so.

01:17:12.040 --> 01:17:12.840
Ja, ich habe,

01:17:13.320 --> 01:17:14.440
hat auch was mit Git zu tun.

01:17:15.900 --> 01:17:16.220
Lustigerweise.

01:17:17.480 --> 01:17:18.500
Ja, auch bei dem

01:17:18.500 --> 01:17:21.060
Backtail-Media-Pool-Request ist mir

01:17:21.060 --> 01:17:22.280
das dann untergekommen,

01:17:22.940 --> 01:17:24.540
weil ich

01:17:24.540 --> 01:17:26.960
hatte halt gar nicht gesehen, dass da

01:17:26.960 --> 01:17:28.000
irgendwelche

01:17:28.000 --> 01:17:30.040
normalerweise hat man

01:17:30.040 --> 01:17:31.860
immer so Linting-Steps oder so, wo man

01:17:31.860 --> 01:17:34.120
jetzt irgendwie Software testet

01:17:34.120 --> 01:17:35.760
oder so, das war da jetzt gar nicht.

01:17:35.840 --> 01:17:37.160
Da dachte ich mir, das ist schon mal ein bisschen komisch.

01:17:37.560 --> 01:17:38.720
Und dann hat irgendwie beim,

01:17:40.020 --> 01:17:41.560
bei GitHub hat dann irgendwie

01:17:41.560 --> 01:17:43.840
das Ding mich angemerkt, so, dein Code ist ja

01:17:43.840 --> 01:17:45.960
irgendwie, da sind ja die ganzen Linting-Geschichten nicht richtig

01:17:45.960 --> 01:17:47.720
und da ist noch was falsch und es ist falsch,

01:17:47.720 --> 01:17:49.220
du warst schon überrascht, weil du hattest doch

01:17:49.220 --> 01:17:51.740
Macht, was da drin definiert war. Genau, und ich dachte schon so,

01:17:51.800 --> 01:17:53.580
ja gut, so mache ich das halt, das ist doch normal und

01:17:53.580 --> 01:17:55.600
das ist doch okay. Und dann dachte ich so, ja,

01:17:55.640 --> 01:17:57.580
wie passiert das eigentlich, dass GitHub das weiß, dass das

01:17:57.580 --> 01:17:59.180
nicht okay ist. Und

01:17:59.180 --> 01:18:01.520
ja, dann wurde ich aber dann auch darauf hingewiesen, so

01:18:01.520 --> 01:18:03.420
ja, wir benutzen hier

01:18:03.420 --> 01:18:05.440
Precommit, benutzen das auch mal

01:18:05.440 --> 01:18:06.100
auch. Und dann,

01:18:06.940 --> 01:18:09.360
und das ist auch ein ganz, das ist glaube ich auch noch ein Projekt von

01:18:09.360 --> 01:18:11.700
Anthony Soti, ich weiß gar nicht, wie man den ausspricht.

01:18:13.560 --> 01:18:15.420
Und man definiert

01:18:15.420 --> 01:18:17.580
das quasi in so einer Art Konfigurationsdatei,

01:18:18.260 --> 01:18:19.500
was man da gerne hätte.

01:18:20.000 --> 01:18:21.340
Und dann sagt man

01:18:21.340 --> 01:18:23.420
Precommit install oder so und dann

01:18:23.420 --> 01:18:25.360
installiert es alle Abhängigkeiten, die man braucht,

01:18:25.360 --> 01:18:27.220
um diese Geschichten machen zu können lokal.

01:18:27.580 --> 01:18:29.360
Aber man muss die halt, diese Abhängigkeiten

01:18:29.360 --> 01:18:31.180
dann auch nicht mehr im Projekt haben. Man hat ja normalerweise

01:18:31.180 --> 01:18:33.120
auch mal so eine ganze Reihe von Dingen,

01:18:33.280 --> 01:18:35.000
ja, was weiß ich nicht, Black, Flag 8,

01:18:35.440 --> 01:18:37.280
dieses ganze Zeugs, auch im

01:18:37.280 --> 01:18:38.860
gleichen Projekt dann immer rumhängen und

01:18:38.860 --> 01:18:41.300
Es ist Death Dependencies quasi, Ersatz, oder?

01:18:42.580 --> 01:18:43.240
Ne, es ist nicht

01:18:43.240 --> 01:18:45.000
Death Dependencies. Death Dependencies sind ja auch nochmal

01:18:45.000 --> 01:18:47.260
andere Sachen, aber man hat halt diesen Kram

01:18:47.260 --> 01:18:49.260
dann da nicht mehr drin, sondern das, ich weiß gar nicht,

01:18:49.500 --> 01:18:50.760
dass ein eigenes Virtual

01:18:50.760 --> 01:18:53.260
Environment installiert wird. Ich weiß

01:18:53.260 --> 01:18:54.600
jetzt gar nicht genau, wie es dann technisch funktioniert.

01:18:54.860 --> 01:18:56.520
Auf jeden Fall ist es dann so, wenn man

01:18:56.520 --> 01:18:58.640
sagt, dann git commit oder so, dann läuft

01:18:58.640 --> 01:19:00.080
das dann halt automatisch durch

01:19:00.080 --> 01:19:02.540
und wenn es nicht

01:19:02.540 --> 01:19:04.620
richtig war, dann

01:19:04.620 --> 01:19:06.620
sagt es irgendwie, nee, kann nicht committen, weil da ist

01:19:06.620 --> 01:19:07.820
halt zum Beispiel irgendwie noch ein

01:19:07.820 --> 01:19:10.600
Flag 8 hat mir gesagt,

01:19:10.700 --> 01:19:12.500
da ist was faul oder es sortiert hier halt

01:19:12.500 --> 01:19:14.580
einfach mal die Imports um mit iSort oder es macht halt

01:19:14.580 --> 01:19:16.620
irgendwie formatierende Code. Man kann seine eigenen Regeln anlegen,

01:19:16.800 --> 01:19:18.560
also jedes Mal muss man über drüber was machen.

01:19:18.700 --> 01:19:20.740
Ja, okay. Genau. Der Dock Swing ist nicht lang genug.

01:19:22.220 --> 01:19:22.320
Ja,

01:19:22.420 --> 01:19:24.620
also das kannst du halt konfigurieren, wie du willst,

01:19:24.760 --> 01:19:27.700
aber es wird dann halt automatisch beim Commit gemacht.

01:19:27.920 --> 01:19:29.860
Ja, das ist schon auch der richtige Zeitpunkt.

01:19:29.860 --> 01:19:30.220
Das ist natürlich auch so ein bisschen hart.

01:19:30.860 --> 01:19:31.280
Ja, klar.

01:19:31.480 --> 01:19:32.500
Doch, es klingt länger als eine Zeiche.

01:19:32.580 --> 01:19:33.080
Das ist ja schon mal super.

01:19:35.240 --> 01:19:36.940
Das kann man ja relativ leicht hinfaken.

01:19:37.040 --> 01:19:37.340
Ja, genau.

01:19:37.560 --> 01:19:41.180
Aber das fällt ja schon mal auf, wenn er nicht da ist zum Beispiel.

01:19:41.600 --> 01:19:42.700
Ja, es ist natürlich relativ hart,

01:19:42.780 --> 01:19:44.340
aber es ist ja eigentlich schon auch der richtige Zeitpunkt.

01:19:44.520 --> 01:19:47.020
Also du kannst nicht committen, ohne dass alles in Ordnung ist.

01:19:47.540 --> 01:19:49.040
Genau, das heißt, es ist damit sichergestellt,

01:19:49.100 --> 01:19:50.480
dass nicht irgendwelcher Quatsch da drin ...

01:19:50.480 --> 01:19:52.080
Also wahrscheinlich kann man das dann auch noch irgendwie umgehen.

01:19:52.460 --> 01:19:53.440
Ist das eine Library oder was?

01:19:54.080 --> 01:19:56.860
Ja, das ist ein Projekt, das ist auch ein Kommandozeilentool.

01:19:57.060 --> 01:19:59.040
Also man benutzt

01:19:59.040 --> 01:20:00.740
das als Kommandozeilentool und dann sagt man im Grunde einmal

01:20:00.740 --> 01:20:02.880
pre-commit install und dann guckt es halt

01:20:02.880 --> 01:20:04.740
in diese Konfigurationsdateien, macht seine

01:20:04.740 --> 01:20:06.580
Magie und danach sind diese Git

01:20:06.580 --> 01:20:08.780
Hooks gesetzt. Aber das muss man quasi

01:20:08.780 --> 01:20:10.760
bei jedem Dev erstmal einmal installieren, damit das funktioniert.

01:20:11.040 --> 01:20:12.100
Ja, okay. Genau.

01:20:13.980 --> 01:20:14.480
Ja, spannend.

01:20:15.040 --> 01:20:16.180
Ja, fand ich auch gut.

01:20:16.480 --> 01:20:18.580
Ja, dann würde ich sagen, sind wir heute durch

01:20:18.580 --> 01:20:20.480
auch mit dem Thema und vielen Dank, dass ihr uns wieder dazugehört habt

01:20:20.480 --> 01:20:22.440
und egal wo ihr seid und morgens, mittags, abends, nachts

01:20:22.440 --> 01:20:24.460
und bleibt uns gewogen, hört uns gerne

01:20:24.460 --> 01:20:26.320
wieder, schaltet wieder rein und euch noch einen

01:20:26.320 --> 01:20:28.160
schönen, was auch immer, Tag, Nacht,

01:20:28.320 --> 01:20:30.080
wie auch immer. Bis demnächst.

01:20:30.420 --> 01:20:31.620
Alles klar, bis demnächst mal. Tschüss.
