Transcript: Python 3.9 und Design Patterns (Teil 1)

· Back to episode

Full episode transcript. Timestamps refer to the audio playback.

Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Python Podcast, 25. Episode.

Heute geht es um Patterns, Software-Patterns, Design-Patterns, Architektur-Patterns.

Wir haben einen Gast dabei, der Herr Toini, hallo.

Hallo immer wieder.

Hallihallo.

Ich bin der Dominik, Jochen ist auch da.

Hoi ho.

Wir sind im Wintergarten, beziehungsweise remote, wie es halt sich für die Pandemie so gehört.

Wir wollten noch sagen, wenn wir aufnehmen, heute ist der 20. Oktober.

2020.

20, 20, 20, 20, 20.

Immer noch 2020.

Ja.

Es zieht sich ein bisschen, finde ich, in letzter Zeit.

Ich erinnere den XKACD, wo

ein Zeitreiser nach 2020 kommt

und fragt, welches Jahr

es ist und er sagt 2020.

Ja, aber das wievielte.

Das ist mir auch nicht so ganz genau.

Ja.

Vielleicht noch ein paar News aus der Szene vorweg.

Genau.

Am 5. Oktober kam Python 3.9

0. Oder war das am 6.?

Ich weiß gar nicht mehr genau.

Ich glaube an dem Montag irgendwie.

Ja.

Watch released on October 5th.

Oh, okay.

Habt ihr alles schon geupdatet?

Nein. Ich habe mich diesmal nicht getraut,

weil letztes Mal mir bei 3.8.0

so ein paar Sachen wie Jupiter auseinander

geflogen sind und ich diesmal darauf

keine Lust hatte.

Ich glaube, ich habe es auch noch nicht

bei uns in die

auswahl mit reingenommen, aber wir haben eh immer

sozusagen das komplette Portfolio von allem

verfügbar.

Ja, ich würde gerne machen, dass bei 1 dann

3, 9, 1.

Ich bin tatsächlich schon quasi zumindest

mit den privaten Sachen umgestiegen, aber

ja, so, das wird

natürlich noch ein bisschen brauchen, bis sich das komplett

durchgesetzt hat,

sodass man es halt auch verwenden kann.

Zum Beispiel Pandas gibt es halt noch keine

Binarys und da ist es natürlich

ein bisschen hässlich, wenn man das irgendwie dann

selber konfigurieren muss.

Das heißt doch, im Bateau habe ich tatsächlich das

in die Travels-Liste

schon mit aufgenommen.

Da kam auch

jemand vorbei, der sich gleich sofort beschwert hatte,

dass es unter 3.9 nicht ging,

weil irgendwas ist rausgeflogen.

Achso, die haben im Async

irgendeine

API, die deprecated war,

tatsächlich gestrichen gehabt.

Ich glaube, in 3.7 hatten sie irgendeine neue API,

um alle Pending-Tasks abzufragen,

eingeführt

und die glaube ich in irgendein

Untermodul verschoben oder so, statt im direkten

Async-Modul. Das war was,

da musste ich dann irgendwie hinterher und in 3.9 war dann

irgendwie die Abletzkompatibilität von der API

jetzt weg. Da

flog es dann auseinander.

Insofern, ja, ich habe es schon

in der Hand gehabt.

Was gibt es denn Neues?

Ganz viele spannende Sachen.

Union Operators.

Was ist das? Was macht man damit?

Ja, zum Beispiel ein Dictionary ist zusammen

schütteln. Ja, ich glaube also wirklich

mehr als

das, was man vorher auch schon mit

Tuple-Unpacking machen konnte. Also

man schreibt halt irgendwie

neuer Key, neuer Value

und dann sagt dann hinten der Sternstern

irgendwie das andere Dict, was man merchen will.

Ich glaube, wenn man jetzt

den Pipe-Operator verwendet, macht es so mehr oder weniger

genau das Gleiche. Ja, aber warum?

Also ich habe es nicht genau verstanden. Ich finde es irgendwie,

das Erste, was ich Python so richtig hässlich fand.

Naja, was fandst du hässlich?

Ja, diesen Operator, diesen Pipe-Operator,

stehen zu haben auf einmal für so eine Operatoren-Urgie?

Ich weiß nicht.

Es wäre halt Mengen-Operations-

Operator an der Stelle.

Es ist halt ein Oder.

Ja, das passt schon.

Das war ja vorher schon immer das Oder

und wenn ich halt über die mengentheoretische

Definition nachdenke,

dann ist das halt genau das, was passiert,

wenn ich halt die Oder-Verknüpfung von

zwei Mengen definieren möchte.

Oder gleich

dieses Assignment, irgendwie ist das komisch.

Naja, das ist halt so wie plusgleich

oder mal gleich.

Das habe ich tatsächlich in Bateau

benutzt oder gleich tatsächlich.

Auch Bateau hat ja so eine komische Syntax, wo wir

plusgleich benutzen.

Wo du so einen Baum aufbaust

mit self plusgleich und dann den

Kindknoten. Und da gibt es nochmal

ein Overloading für die

Pipe, wo man dann sozusagen

eine spezielle Form von Verkettung hat.

Insofern finde ich das ganz cool, dass die jetzt auch die Pipe

genommen haben. Da fühle ich mich in meiner Wahl

von vor sechs Jahren bestätigt.

Ja, okay.

Ja, also ich glaube also so, was es halt, es sieht halt, ich finde es sieht schon besser aus, als wenn man jetzt immer mit den Sternen, Sternsteinen, da muss man mal so ein bisschen nachdenken, was man jetzt eigentlich genau machen wollte, ist ein bisschen hübscher, aber ist jetzt keine so weltbewegende Änderung.

und es ist vor allem, es erzeugt halt ja ein neues Dict

also ganz klassisch

war ja immer das Thema, dass du

Dict Update sagst

ja und dann macht das was anderes

als man denkt, das modifiziert

dein Original Dict

ja

ja

insofern ist vielleicht ein bisschen

eindeutiger, was es macht

ja also mein Lieblingsfeature

tatsächlich oder meine Lieblingsneuerung

Meine Lieblingsneuerung ist der Packparser.

Ehrlich gesagt bin ich jetzt kein

Experte für so Parser-Geschichten, aber

ich fand das schon eigentlich ganz

nett, was man damit dann eventuell

alles dann zusätzlich so machen kann.

Also es hieß irgendwie so, ja,

das macht dann irgendwie neue

Sprachfeatures einfacher oder so. Das stimmt

nicht so ganz. Also

so wirklich viel einfacher

wird dadurch nicht, aber es macht halt so ein paar Sachen,

die bisher sehr hässlich waren. Du musst dann den Hörer noch mal

kurz erklären, was überhaupt ein Packparser ist, bitte.

Oh nein! Das wollte ich

Das wollte ich eigentlich vermeiden. Das kann ich ehrlich gesagt nicht wirklich. Also es gibt halt diese Standard-Parser für so Programmiersprachen. Die meisten Programmiersprachen sind halt, oh je, jetzt muss ich tief in die Informatik hinabsteigen. Da gibt es halt so, Programmiersprachen sind meistens, die Grammatiken dafür sind so kontextfreie Sprachen. Also, oh je.

Ja, genau.

und sogar eine bestimmte

Form davon,

so LR1 Grammatiken oder so,

das ist halt

LR1

Grammatik zum Beispiel.

In dieser Form ist auch zum Beispiel

die Java Sprachspezifikation, das ist also das erste,

was ich, sollte man sich im Studium,

als ich mal angefangen habe, irgendwie sollte man sich

das mal kaufen. Habe ich dann gemacht, fand ich sehr langweilig,

ehrlich gesagt. Das war ein sehr dickes Buch,

in dem stand halt die

komplette Sprache

und halt Grammatik drin und da lasse ich schon so was

in komische Abkürzungen und das ist halt genau die,

die halt beschreibt, ja,

wie die Grammatik für diese Sprache aussieht

und wenn man

das sozusagen in dieser Form notiert hat, dann kann man

das in einen Parser-Generator werfen

und dann... Der liest die Sprache

und weiß, was der machen muss.

Der gibt einem dann einen Parser,

der genau diese Sprache akzeptiert.

Und das sind dann so Dinge wie...

In letzter Zeit habe ich da wenig mit zu tun gehabt.

Früher ganz mehr

sowas wie YAK zum Beispiel

gibt es da

auch so ein rekursives Akronym

Justiner sagt Compiler Compiler

dem kann man sowas vorwerfen

und der spuckt dann halt ein Parser aus

und das gab es dann noch mit Lex

und Bison und

ich weiß gar nicht mehr so genau

und genau, damit kann man Parser generieren

und die akzeptieren dann solche Sprachen

und die meisten Programmiersprachen sind halt

so irgendwie diese

Geschmacksrichtung von kontextfreier Sprache

und

Python Parser war halt auch sowas

aber

das Problem ist, es gibt halt so ein paar

Features, die passen da nicht so richtig rein

oder ein paar Dinge in der Sprache

die funktionieren damit halt nicht so richtig

und deswegen gab es da sowieso

schon immer so Ausnahmen

und deswegen ist es halt bisher so ein bisschen hässlich gewesen

also es gibt zum Beispiel

es gibt halt, ich kriege das auch nicht alles auf die Reihe

aber es gibt halt

der Parser nimmt halt sozusagen den Text

also irgendwie ein Python-Programm

und gibt dann halt

ein Abstract Syntax Tree aus

und der wird dann von dem Compiler

verwandelt in Bytecode

oder so und da wird dann halt irgendwie interpretiert

und das gibt dann halt so diverse Teile

und

das Problem ist irgendwie, dass manche

Sachen halt

verteilt sind auf unterschiedliche Teile

also dass es halt nicht so ist, dass es

oder der Parser bisher

bestimmte Sachen halt nicht so einfach damit parsbar waren

und der ist auch handgeschrieben, also das ist halt irgendwie,

wenn man sich das angucken will, gibt es

ein Modul, das nennt sich

ast.c oder so

in Python-Source-Code, das ist der

alte Parser,

paar tausend Zeilen handgeschriebenes

c, ziemlich fies, also

genau, und

der ist halt nicht automatisch

generiert, was halt schon mal nicht so schön ist,

weil das halt dazu führt, dass er nicht so richtig

konsistent ist und so und sich

manchmal komisch verhält und

das Problem eigentlich dabei ist, wenn man jetzt sozusagen

teilweise sind halt Sachen, ich kriege das nicht mehr richtig auf die Reihe,

wenn man zum Beispiel rechts neben dem Gleichheitszeichen,

weil das Gleichheitszeichen ist irgendwie ein Problem und wenn man da mehrere Sachen stehen hat, also mehrere

Dinge, die addiert werden oder so, dann muss das hinterher nochmal im Compiler

umsortiert werden, weil der Parser noch nicht

irgendwie ordentlich gemacht hat. Und das heißt, wenn man jetzt irgendwie so ein Problem hat,

auch ein Syntaxproblem.

Funktion A plus Funktion B

rechts von einem Gleichheitszeichen,

dann ist halt komplett unklar,

wenn jetzt da irgendwo ein Syntaxfehler ist, wo der eigentlich

passiert. Weil

das ja dann schon einem erst

im Compiler irgendwie um die Ohren fliegt oder so.

Sodass halt

der Python-Grafiker auch gar nicht

sagen kann, wo der Syntaxfehler ist, was

halt eventuell ein Problem sein könnte.

Wenn man nicht mehr weiß, wo der Fehler ist, dann ist es halt schwer, den

zu fixen. Und das sind halt so Hässlichkeiten.

Sodass man halt da diese

diese Überprüfung, ist das jetzt korrekter

Python-Code oder nicht, halt nicht an einer Stelle

passiert, sondern halt über ganz viele Teile

verteilt ist, ist das halt, sind manche

Sachen halt einfach total hässlich und

ich habe

da so ein

Podcast

Podcast-Init

da waren die beiden, die

den Pack-Baser hauptsächlich gebaut haben

jetzt in Python 3.9 zu Gast

und haben da halt so ein bisschen was erzählt, was sie da gemacht

haben.

Einer von denen meinte so, also

und

eine User-Anfrage war halt so,

warum können wir das in RIS

Context Manager mit diesem

RIS-Statement nicht einfach so machen

wie bei Imports oder halt mit

bei Strings, dass wir da

Klammern drumherum machen und dann haben wir mehrzeilige

Dinger, weil mehrzeilige RIS-Statements geht halt

einfach nicht.

Und das hat er dann versucht umzusetzen

im alten Parser und das ging halt überhaupt

gar nicht. Also er hat da irgendwie

wohl eine Menge Sachen probiert und es ging einfach nicht.

Und er meinte so,

und Jochen unterhalten sich über die Programmiersprache Python

Er braucht sogar mehr RAM.

Ja, genau. Also das war der Grund, warum man das

früher nicht gemacht hat, weil man

muss jetzt alle Tokens im Hauptspeicher halten und das

war halt früher ein Problem, heute

nicht mehr so. Also genau,

er braucht einfach mehr RAM.

Irgendwer hatte auch was

erzählt von, dass sie jetzt per Default sagen,

also mehr als eine Million Zeilen

in eine Python-Datei wollen sie

jetzt bitte nicht mehr sehen.

Ja, okay, aus dem Kreise.

Oh Mist, was war ich denn jetzt?

Da habe ich eine ganze Firma

drauf aufgebaut

Ja, also

von der Performance her ist kein großer

Unterschied, wohl von der Laufzeit und Hauptsprecher

braucht es ein bisschen mehr, aber

genau, das ist das tolle Ding, was man eventuell jetzt damit machen kann

Was sonst sehr schwer geworden wäre

ist, da gibt es

auch ein PEP jetzt, weiß ich nicht welche Nummer

Pattern Matching

Bin mal gespannt, ob das

angenommen wird für Python 3.10

dass man halt so

Lisp-Style-Makros hat, beziehungsweise

halt in funktionalen Programmiersprachen ist das schon länger

oder das ist halt ja so eins der grundlegenden

Geschichten und

ja, in Python ging das halt

auch vor allen Dingen wegen dem Parser

bisher nicht und das

geht dann eventuell und wenn man das darin hat, ist

natürlich schon nett, hat man so eines der zentralen Features

von funktionalen Programmiersprachen auch mit drin

Was sind denn Lisp-like-Makros?

Ja, das

müssen wir mal irgendwann machen, wenn wir irgendwie auch

so ein bisschen, so ja, noch mal funktionale Programmiersprache und und und und und und und und und und und und und und und und und und und und

Ja, ein Bug ist auch schon aufgefallen wohl.

Also Match war,

achso, ja, vielleicht tatsächlich,

das ist

eine bessere Variante

dessen, was sonst in anderen Sprachen das Case

gewesen wäre.

Nur mal so als

zur groben Einordnung. Also

mit dem Match geht es dann am Ende

tatsächlich darum, die, wenn man sehr

komplexe If-Else

Zweige hat,

dann kann man die damit ein bisschen hübscher abbilden.

also substanziell

schon

Warum hat man das nicht Case genannt?

Das müsste ich jetzt nachlesen

Also es macht

schon glaube ich noch ein bisschen mehr

Ach, keine Ahnung

Genau, einen Bug gab es auch schon

da wird jetzt dann wahrscheinlich in 3.9.1

gefixt und zwar

was der alte

Parser konnte und was jetzt halt mit dem neuen

nicht mehr geht, ist,

wenn man

Tupple Unpacking, halt auch so Stern

irgendwas in, with

so Context Managern verwendet,

dann funktioniert das nicht.

Tja,

aber es ist halt bisher niemandem aufgefallen, also so häufig

scheint es nicht verwendet zu werden, aber

das klappt schon irgendwie nicht. Achso, das ist auch vielleicht ganz

interessant, also in 3.9

sind beide Parser drin, man kann auch

irgendwie per Kommandozeilenoptionen sagen

minus x irgendwas, Old Parser oder so,

verwendet doch bitte den alten, wenn man

irgendwie mit dem neuen ein Problem hat. Der neue ist

defaultmäßig aktiv

und der alte ist aber halt

noch drin und

mit Python 3.10 wird es dann halt so sein,

dann wird der alte Parser komplett rausfliegen und nur noch

der neue drin sein.

Okay.

Was mit Tablet Unpacking in Context Managern, das habe ich jetzt

nicht so ganz verstanden. Warum geht das nicht oder ging das

vorher auch nicht? Doch, das ging vorher schon.

Das hat bloß keiner gemacht. Warum auch?

Aber

aber ja, jetzt geht es nicht mehr.

Also warum will er das denn nicht machen?

Naja, also warum, also

das ist halt,

niemand versteht dann, was du tun willst, wahrscheinlich.

Ich überlege gerade, wie die genaue Syntax ist, was da kaputt geht.

Hast du den Bug irgendwo da?

Naja, momentan müsste ich auch gerade suchen.

Ich versuche so leise wie möglich zu tippen.

Also ich kann mir schon vorstellen,

warum nicht im Contact Manager einfach irgendeinen Tupel

anpacken, was das doch durchhört.

Nee, nee, die Frage meint

wahrscheinlich oben in der Riff-Expression.

Ja, in der Expression selber.

Und dann irgendwas mit Tupel-Unpacking machen.

Also ich sehe da echt keinen Anwendungsfall für.

Und es ist glaube ich, also die haben da ja die komplette

Standard-Bibliothek durchgejagt und noch viele

PyPI-Fakete und sie haben es nie aufgetreten.

Also das ist nicht so, dass das irgendwie dauernd gemacht wurde, sondern das hat bisher wohl noch nie jemand gemacht.

Quasi. Also jedenfalls nicht ein Code, der irgendwie häufiger verwendet worden wäre.

Also, ja.

Es war nur, das ist halt schon mal aufgefallen, dass da ein Unterschied zwischen den beiden Passern gab.

Ja.

Tja, was haben wir denn noch so?

und Jochen unterhalten sich über die Programmiersprache Python

Ja, das ist schon hilfreich

Ja, ansonsten

Zeitzonen-Handling

ist jetzt irgendwie mit drin

Das habe ich noch nicht angeguckt

weil ich bin seit irgendwie 15 Jahren

mit PyTZ unterwegs

und PyTZ hat halt den Vorteil

das ist unabhängig, das ist halt so ein Ding

die Zeitzonen-Datenbanken werden halt ständig

aktualisiert und geändert

und ich bin mir gerade nicht sicher

haben die

da irgendwie die Datenbanken mit dabei

oder ist das eine API?

Genau, das ist halt auch der Grund, warum

im DateTime-Modul

in der Standardbibliothek

waren diese

Zeitzonen-Datenbanken auch nie drin, wohl aber

eine API dafür, wie man da seine eigene Datenbank

oder sein eigenes Objekt, das halt implementiert,

Zeitzonen-Objekt irgendwie

reintun kann, weil sich die Leute gesagt haben,

Python-Release-Zyklus, viel zu lang für diese

Updates und dann wollen die Leute das mal selber machen

und dann haben es die Leute natürlich nicht selber gemacht,

weil keiner Bock hatte,

das zu machen und

und ja, wie es jetzt wohl ist, ist, dass...

Ja, die nehmen die System Time so, weil sie haben eine API dafür, um das reinzuziehen.

Ja, und genau, auf Windows gibt es noch eine komische Geschichte,

da gibt es dann ein First-Party-Package, was man dann noch installieren muss,

TZ-Data oder sowas.

TZ-Data, ja.

Dann geht das da wohl irgendwie auch, ja.

Aber genau, so ist das dann.

Ja, das ist so als Fallback gedacht, für wenn das andere nicht da ist.

Und die intern

funktioniert das wohl

mehr oder weniger genauso wie

DateUtil oder sagen wir so, das ist auch

also wie

DateUtil das macht, also ich glaube

das ist auch von dem Autor von

von DateUtil irgendwie

meine ich jedenfalls gehört zu haben

dass der das von dem das ist und das

es implementiert halt so die Kerngeschichten

aber viele von den fancy Features von DateUtil

sind halt nicht drin, aber

so die Kerndinge, ja

Ja

Noch was?

Noch irgendwas

Naja gut, da gab es noch irgendwas mit Dekoratoren

und Syntax, dass man da

konnte man früher immer nur

bis jetzt halt immer nur Funktionen verwenden

und jetzt kann man halt auch irgendwie

ein Dikt nehmen und dann eckige Klammern oder so

das ging vorher auch nicht so richtig

und das geht jetzt

das wird wahrscheinlich auch kaum jemand machen

in der Sperre.

Jawohl, da kann ich mir das KMR vorstellen.

Man könnte sich vorstellen, man hatte

irgendwie ein Dikt von Dekoratoren oder so, wo die

Values halt irgendwie Funktionen sind

und dann wählt man halt das Ding aus,

was man halt, und da hätte man halt

bisher immer irgendwie eine Extra-Funktion

haben müssen, die dann halt

die richtige Funktion, innere Funktion auswählt

und jetzt geht es halt direkt.

Auch nicht so schlecht.

Es ist ja eine Frage von, in solchen

Momenten immer bei diesen

syntaktischen Kleinheiten,

und dann kann man ja immer dieses berühmte Dokument des PHP a fractal of bad design rausholen,

dass du dich halt irgendwie darauf verlassen können möchtest, wenn gesagt wird,

okay, hier hinter dem Ad kommt halt eine Expression, dann kann ich hier auch bitte alles machen, was eine Expression halt kann.

Und wenn das halt nicht geht, dann steht man immer traurig da und fragt sich, was soll denn der Quatsch eigentlich.

insofern, ich finde das einfach das ist halt so das Thema, wenn das auch gerade was ist, was der neue Parser vielleicht besser unterstützt dann all for it Was ist PHP a fractal of bad design? Also, um nicht auf anderen Sprachen rumzuhauen gibt es aber ein wirklich berühmtes Dokument zum Thema, warum PHP so ein massives Problem im Sprachdesign hat und da gibt es in dieser Blogpost, der ist jetzt auch

schon 10 Jahre alt oder so. 2012.

8 Jahre.

Und

da geht es sozusagen darum,

dass diese Herangehensweise

des Sprachdesigns, und da ist Python ja

schon lange ein Vorreiter gewesen, dass es halt eine

explizite Sprachdefinition gibt,

aus der dann halt das C-Python

nur in Anführungszeichen

die eine Implementation ist.

Und es ist klar, es kann auch andere

Implementationen geben.

Und hier

nämlich an mindestens ein Thema

und die Funktionen, die er in den Parseur integriert hat, mit einem Variablen-Namen aufgerufen werden, aber niemals mit einer Expression, wo du dann von dem Ergebnis den Typen haben möchtest.

weil halt jemand das in den Parser so reingestrickt hat

und dieser Artikel geht das sozusagen in

arg detaillierter Form durch und nimmt da irgendwie tausend von den Sachen auseinander

und sagt halt hier, was willst du jetzt noch sagen, wenn du irgendwie nur noch von einem zum anderen stolperst dabei

ja, der wäre jetzt mal ganz interessant zu lesen

zum Thema irgendwie ein bisschen analytisch auseinander genommen

was das liebe PHP da so ein bisschen

auf die schiefe Bahn geraten lässt

Ja, müssen wir mal in die Shownotes packen

Ja

III.II

oder sowas

Ja

aber ich glaube

das war es dann auch schon mehr oder

weniger, ne?

Ich glaube sonst war da eigentlich nichts drin

Ja, ich glaube irgendwie noch was zu typen oder sowas

Oh ja, stimmt, man kann jetzt irgendwie

man muss nicht mehr

diese List mit Großbuchstaben

vom Typing importieren.

Wahrscheinlich war das halt auch so gedacht,

wer weiß, wie lange, ob die Leute das gut finden

mit dem Typing, Typings und so.

Nehmen wir mal

nicht, irgendwie machen wir nicht den Aufwand,

das direkt so zu ändern.

Und jetzt muss man das halt nicht mehr aus Typing

irgendwie

List mit großem L importieren, sondern kann halt

die Build-ins verwenden und das funktioniert

dann halt auch in den Typings.

Genau, das ist ganz nett.

Das macht es ein bisschen

einfacher das zu schreiben und muss nicht mal nachgucken, welche Impost das jetzt waren.

Ja, was steht an Veranstaltungen an?

Habt ihr irgendwelche?

Oh, hab ich jetzt dummerweise gar nicht so richtig nachgeschaut.

Die DjangoCon ist gerade vorbei.

Ja, gab es eigentlich die PyCon auch jetzt?

Oder war die PyCon dieses Jahr virtuell? Ich weiß gar nicht.

Welche meinst du, die deutsche?

Ja, die G.

Ne, die haben wir tatsächlich verschoben.

Also wir hatten relativ

zeitig im Jahr mit den, also es wäre

jetzt wieder in Berlin gewesen. Genau, letzte Woche

war es gewesen eigentlich.

Genau, und wir haben aber relativ frühzeitig

mit dem Veranstaltungsort

wie Wärm gewesen im

Haus des, nicht Haus des Lehrers, hier daneben

an.

In Berlin? Genau.

Ach, wie heißt denn das noch? Da wo immer der

Zivilkongress war. Da wo immer der Kongress war, genau.

Dieses UFO.

Ja, da wären wir gewesen eigentlich und wir haben mit denen dann halt, das war halt so ein bisschen schwierig, weil im Januar ja wirklich, im Februar, März war das, März, März, nicht klar war, wie wird denn das jetzt sich über das Jahr eigentlich entwickeln und tatsächlich jetzt sehen wir ja gerade auch, dass die Zahlen schon wieder schwierig sind und Massenveranstaltungen sind ja eh abgesagt bis mindestens Ende 2020 und wir hätten gerechnet, also in einem regulären Jahr wäre unsere Hochrechnung glaube ich bei knapp 2.000 Euro,

22 schon rausgehandelt. Die haben ja auch das Problem.

Auf der einen Seite müssen sie irgendwie sehen, wo sie

bleiben und auf der anderen Seite wollen sich natürlich auch nicht

alle Leute verbrennen, die eigentlich jetzt

regelmäßig Veranstaltungen mit ihnen machen.

Ich bin ein bisschen froh, dass wir halt jetzt

irgendwie planmäßig schon für Berlin

geplant hatten und nicht für

Hinterpose Muckel,

um dann sagen zu müssen, so auf die nächsten

x Jahre müssen wir nach Hinterpose Muckel

ansonsten

pleite,

wären wir nicht pleite, aber

ansonsten müssen

im November.

Da gehen demnächst noch Einladungen raus,

wer beim Python-Verband Mitglied werden will.

Stimmt.

Dafür muss er tatsächlich noch mal kurz Werbung machen.

Die Webseite kurz nennen.

Genau, das wäre der

python-verband.org

der Python Software Verband

als die deutsche Interessenvorredung.

Und eine unserer

Hauptaktionen, das war dieses Jahr

leider auch ein bisschen

wenig durch Corona,

und was wir in der Webseite sehen, ist, dass wir alle möglichen Community-Aktionen fördern.

Sowohl organisatorisch als auch mit Geld.

Das heißt, wir verstehen uns da ein bisschen als eine Drehscheibe.

Python selber ist ja gut bekannt, aber was wir stark unterstützen wollen,

ist halt Python noch in Communities zu tragen, die es vielleicht nicht so kennen

und aber auch Veranstaltungen zu fördern.

Das heißt, man kann da auf der Webseite unser Förderprogramm nachschlagen

und dann kann man sich relativ unkompliziert Geld für Ideen abholen,

die man mal mit, wie man Python an andere Leute ranbringen will, mal was coden möchte, etc.

Genau.

Und im Corona-Jahr war es jetzt auch so, dass wir tatsächlich ein, zwei schon länger bekannte Partner,

da gibt es die TechKids zum Beispiel im Schwäbischen,

die haben jetzt auch ganz schön duttel gelitten, weil denen die ganzen Veranstaltungen weggebrochen sind,

mit denen sie normalerweise dann ja auch wieder Teilnahmegebühren reinholen

und haben da jetzt dieses Jahr im Fördertopf

tatsächlich dann auch eher mal großzügig

gesagt, okay, wir sponsern euch jetzt auch mal, wenn gerade

nichts los ist, damit das jetzt hier

über die Corona-Zeit

nicht alles zerbricht einfach, was die Leute

aufgebaut haben.

Ja, das ist tatsächlich viel

Ort sein, größeres Problem, ja.

Tja, ja.

Sonst ist dann demnächst Weihnachten. Ich habe heute die erste

Weihnachtswärmung gekriegt.

Ja, tatsächlich.

Weihnachtswünsche.

Ja, geht schnell vorbei mit so einer Pandemie

Ja

So oder so

Ja, also genau

Ich weiß nur, EuroPython

war jetzt auch vor kurz

Die Vorträge sind irgendwie da

und DjangoCon, das wollte ich mir auf jeden Fall

angucken, aber habe ich noch nicht geschafft

Gibt es auch die ganzen Vorträge

online und was jetzt in Zukunft

kommt, weiß ich gar nicht, weil ich es nicht

nachgeguckt habe

Ja, wir verpassen übrigens gerade wieder das Django Meetup Cologne.

Ja, ich weiß, aber das ist halt dann blöd.

Die Frostcon war auch noch, das ist jetzt auch so fünf, sechs Wochen her, glaube ich.

Da hat es ein bisschen gedauert, die haben jetzt auch erst vor, glaube ich, zwei, drei Wochen dann die Videos online gehabt.

Es gibt, glaube ich, noch wieder so eine neue Anmeldung für das nächste Jahr, die 21, die auch online statt sein wird.

Äh, Forstdem, diesmal.

Forstdem, achso, das ist dann Februar, Januar, Februar, die Forstdem.

Genau.

Nee, ich meinte die Frostcon.

Genau, die ist normalerweise

Sankt Augustin

Genau, ja

Ja, ansonsten

was mir noch so eingefallen ist, was jetzt geht

was früher nicht ging

iSort und Black sind kompatibel

Ja

das ist auch nett

Wie kam es?

Ich weiß es nicht genau

also

mit irgendeinem

Update von iSort ist das jetzt

und das war dann irgendwie erledigt.

Also iSort hat was gemacht damit Black nicht mehr dazwischen punktet Ja irgendwie so genau und ja jetzt geht es halt man kann es halt beides verwenden und hat dann da kein nicht mehr so

dass das eine immer die Sachen vom anderen umsortiert

was ja irgendwie ein bisschen doof ist. Jetzt müsste man das nur noch in

PyProjectHumil konfigurierbar machen, genau wie

PyTest und

Lake8 und dann... PyTest ist das?

Ist das schon?

Ja, aber mit so einem komischen

Ja gut, der Key

ist so ein bisschen komisch. Genau, PyTest

Ini Options oder so so ein Quatsch.

Ja.

Wobei ich sagen muss,

wir haben jetzt tatsächlich Black an ein paar

Stellen wieder zurückgebaut

und ich breche noch eine Lanze für alle

Leute, die sozusagen neben Schwarz

noch ein bisschen Grau haben wollen.

Ja.

Und empfehlen mal noch ins Japf reinzuschauen.

Japf, okay.

Ja, Black wird auch ein Problem kriegen.

Black verwendet auch den

alten Parser

und spart es uns ab Python 3.10,

und wird es dann halt

einfallen lassen, weil das geht dann nicht mehr.

Kannst du kurz was zu JAPF noch sagen?

Ja, JAPF ist so ein,

wir waren ja vorhin schon beim JAK,

der Yet Another Compiler Compiler

und JAPF ist der Yet Another Python

Formatter und

die haben sich tatsächlich eher auf die Fahnen geschrieben,

dass das Ding ein bisschen

konfigurierbarer ist.

Auch mit einer JAPF-Ignore, ich hab's gerade gesehen.

und

der erzeugt für mich,

finde ich, deutlich lesbareren

Code. Also das ist die,

ich komme persönlich mit der

Blackformatierung an vielen Stellen so richtig

gar nicht klar und

finde sie einfach

urpot hässlich. Ich fand sie auch sehr

agil, aber Jochen hat sie mir immer aufgezogen.

Ja, sorry.

Also ich unterstütze volle Kanne

das Thema, einen

Autoformatter einzusetzen,

Aber ich finde, Beck ist halt nicht der weiße Westerfluss

Ja, das mag, also ich verstehe das durchaus

Ich finde auch, ich habe so ein bisschen Schwierigkeiten mit den

Anführungszeichen, ich habe auch vorher immer Single-Codes

verwendet und da so, ah

das ist schon so ein bisschen, auf der anderen Seite würde ich sagen, naja gut

also

selbst wenn man es nicht so hübsch

empfindet

wenn alle den gleichen Autoformatter verwenden

ist das ein so viel größerer Gewinn

als, dass ich dann sage

nur gut, dann gebe ich dafür die persönlichen

Referenzen auf. Aber ja, ich kann auch

verstehen, dass man das...

Weil mein Streit sozusagen schon

über das, was ich als persönliche Präferenz

empfinde, rausgeht,

weil es verletzt mein ästhetisches

Gefühl so, dass ich wirklich daneben

stehe und sage, nee, das ist

volle Kanne gegen

die Designziele von Python

als Sprache.

Ja.

Also das ganze Thema, dass die Indentation mir Dinge

sagt und dann irgendwie

über x Dutzend Zeilen hinweg wieder schließende

Klammerorgien zu sehen, dafür brauche ich kein Python. Also dann brauche ich kein Python,

kann ich da was Skript schreiben.

Ich verstehe ja, warum das passiert.

Sie versuchen ja eine Formatierung zu machen,

die möglichst wenig Diff erzeugt. Wobei ich das bisher

auch nicht gesehen habe. Da hätte ich gerne mal tatsächlich noch eine

Metrik gesehen. Und ich muss aber sagen, das verletzt dann so ganz

für mich jetzt halt an und wir haben jetzt tatsächlich

in einem Projekt, einem größeren Projekt,

das eben nochmal umgestellt von Black auf einen

anderen Formatter. Auf Japf.

Auf Japf halt mit entsprechenden anderen Optionen

und

siehe da, plötzlich hat man wieder so ein, ah stimmt,

so muss das aussehen, danke, das ist Python.

Kannst du dafür mal die

Config irgendwie teilen

mit uns in den Show Notes?

Na klar. Das wäre super, weil das da finde ich

sehr spannend, weil ich finde Black auch

mega ultra hässlich und genau das, was du sagtest,

also ein paar Sachen, wo ich dachte, wieso macht das

und das ist auch eklig.

Ja, naja, gut.

Ja, ist schon

was dran. Dazu fällt mir gerade noch ein,

ich habe letztens einen Podcast gehört,

also ich höre den ab und zu,

gefällt mir eigentlich, also mir

gefallen ja auch so Formate, die so ultra lang sind und das

ist halt auch so einer schön lang,

der heißt irgendwie Lex Friedman

und der spricht so mit

allen möglichen Leuten und halt

darunter sind halt auch viele der so

Korriphäen.

zum Beispiel hatte er letztens

ein Interview mit

James Gosling

zu dem

quasi Entwickler

von Java

und das fand ich

ganz interessant

und der erzählte dann halt

auch so, ja also

was ihn dann dazu gebracht hat, Java

sich auszudenken war halt

seine lange Erfahrung mit C

auch sowas was ich nicht wusste, der hat

und Emex irgendwie geschrieben

in C oder die erste

ordentliche Version von Emex

und stand dann irgendwann vor der Entscheidung, okay, ich mache

jetzt entweder den Rest meines Lebens Emex

oder halt nochmal was anderes und dann

dachte ich so, naja, Emex, so geil ist es dann, also

weiß nicht, muss auch nicht sein.

Dann hat er lieber was anderes gemacht und das abgegeben irgendwie.

Also Emex und Java

sind eng verwandt, interessant.

Naja, also

in gewisser Weise.

Aber er hat halt auf jeden Fall sehr, sehr viel C geschrieben.

Die ungleichen Zwillinge.

und dann auch

größeren Projekten und dann sind

ihm halt so Dinge aufgefallen, die immer wieder schief gehen

in C und dann Java war halt sozusagen der Ansatz

also mit diesen großen Fehlerklassen

die halt C immer wieder

ganz böse Probleme machen

aufzuräumen und das ist ja auch dann irgendwie gelungen

aber

der sagte dann etwas, als es

darum ging, wie das dann

so ästhetisch aussieht

daher die

Anknüpfung sozusagen

und er meinte so, ja, also wenn ich irgendwie

Code lese, es gibt ja immer so Leute, die sagen dann so

oh, ich finde das ästhetisch ist aber nicht so

hm, gefällt mir nicht so richtig

und er so, mir war das immer alles total egal

ich habe da nie den Code gesehen

wenn ich irgendwie so eine Funktion angucke

dann sehe ich immer nur so, dann habe ich da

so eine visuelle, so eine Bildvorstellung von

so wie so Zahnräder von einer Maschine

und dann sehe ich, ob das das Richtige tut oder nicht

und wie die Syntax von der Sprache ist und wie die

Sprache aussieht, das sehe ich gar nicht

das ist mir auch total egal

und dann dachte ich so, okay

Ja, das erklärt natürlich einiges.

Aber

das ist aber halt, da ist er halt noch

auch schwierigen Positionen, weil er hat den Quatsch halt erfunden

und

mir geht es halt auch so, wenn ich irgendwelche

Tools baue und erfinde,

dann sehe ich da, wenn jemand die Tools

verwendet, halt auch mit einem Schlag die

Zahnräder. Das ist aber halt

kognitiv ein völlig anderer Prozess, als

wenn ich das halt nicht erfunden habe

und ich das

verarbeiten muss, was da steht. Und das ist

sozusagen, und da gibt es, jetzt habe ich

und die Programmiersprache Python

oder vielleicht sind unterschiedliche Leute da halt auch

einfach unterschiedlich, vielleicht gibt es Leute,

denen ist das halt egal, die sehen halt wie

die Mechanik dahinter

direkt aussieht und

können sozusagen an dem Code vorbeigucken, aber

mir geht das auch nicht so.

Ich bin sehr an der ästhetischen...

Es ist viel schöner, wenn man die ästhetischen Patterns

direkt sehen kann und die einem klar ins Auge springen.

Ja.

Willst du ein anderes Thema

einleiten? Ich habe gerade versucht, einen kleinen

Übergang zu finden.

Ich weiß nicht, ob es mir geglückt ist.

wie geschickt.

Ja, aber es war wirklich so. Wenn man das sehen kann,

dann kann man doch auch diese Patterns auch mit einer gewissen

Ästhetik betrachten.

Und deswegen ist vielleicht diese Ästhetik der Sprache

für

manche wichtiger, vielleicht für einige

unwichtiger, aber ich finde, es ist ein sehr essentieller Teil.

Also gerade, weil auch die Hürde dadurch

deutlich gesenkt wird. Selbst wenn es jetzt

ein sehr hochentwickeltes Feature ist,

ermöglicht es halt auch einen deutlich einfacheren

Einstieg, weil durch diese ästhetische

Klarheit man das Konzept auch

deutlich einfacher verstehen kann.

Man kann ja auch tatsächlich Ästhetik mal zur Seite legen und an der Stelle einfach, also es gibt ja mehrere andere Kriterien, die man ansetzen könnte, eben zum Thema Lesbarkeit, Menge der Zeichen auf dem Bildschirm, Menge an Noise, an syntaktischem Drumherum und so.

und es gibt auch bestimmte Sprachen, bei denen ich halt sage, da ist es mir wieder zu wenig.

Also Python ist halt tatsächlich für mich so die Sweet-Spot-Sprache,

da ist mein Gehirn super drauf angesprungen damals und extrem gut drin.

Mit Ruby tue ich mich zum Beispiel extrem schwer.

Ruby hat halt dieses Thema, dass sie sehr viel metasyntaktisch arbeiten

und das heißt aber, du musst teilweise schon überlegen,

hier ist ein Leerzeichen, deswegen bedeutet jetzt gerade,

und wenn das da hinter der Funktion ist, dann

da musst du schon auch

in diesen Mustern ganz schön

ganz schön arg drin stecken, um das halt

wirklich lesen zu können und ich habe bei Python

halt immer das Gefühl, egal

wie es geschrieben ist, irgendwie

kriege ich es dann schon auch wieder relativ schnell

auseinanderklamüsert

aber ich merke auch, oh, jetzt ist es

auf eine Art geschrieben, die ist irgendwie von

durch die Brust ins Auge und

war irgendwie nicht zum Lesen gedacht

Ja

Ja, man muss ja schon irgendwie

Methode relativ schnell begreifen können irgendwie,

als ein Ziel, wenn man das so vernünftig

machen möchte.

Ich glaube auch da wieder,

dass halt für unterschiedliche Leute

vielleicht da unterschiedliche

Trade-offs besser funktionieren oder schlechter

und irgendwie so

wie sieht das aus oder wie kann man,

wie schreibt man Dinge dran, ist halt irgendwie so das

User-Interface der Sprache,

was ich auch letztens noch gehört habe,

was ich ganz interessanten Ansatz fand,

das war, wo habe ich das hin

gehört,

dass es ja auch noch andere Aspekte gibt.

Also genau, das war auch in einem

Interview-Podcast mit, glaube ich, Chris Lettner,

der Swift

und Clang und so

gebaut hat. Und

das hatte ich vorher noch nicht so richtig auf dem

Schirm, weil ich dachte immer so,

was halt dann an Code dasteht, ist halt das

Entscheidende. Und der meinte dann halt auch so, ja,

also User-Interface der Sprache ist sehr wichtig und

Python voll gut. Wusste ich auch gar nicht, dass er da so

meinte, das ist total super.

Das Problem ist nur, es gibt halt auch noch andere

andere Dinge, die halt auch eventuell wichtig sind, wie zum Beispiel so etwas wie

wie gut ist das denn jetzt nicht, wenn ich da drin irgendwas programmieren will,

was dann irgendwie mein Problem löst, sondern wie ist das eigentlich, wenn ich jetzt

ein Framework da drin entwickeln will oder irgendeine Library, ist das denn dann

immer noch gut, weil bei Python hat man dann zum Beispiel das Problem

okay, wenn das jetzt irgendwas ist, was

CPU-bound ist sozusagen, dann hat man wahrscheinlich, wenn man

und Jochen unterhalten sich über die Programmiersprache Python

gibt es keine konsistente Art mehr, das so richtig zu debuggen.

Und das ist natürlich schon so ein Punkt.

Oder was er auch meinte, ist dann halt sowas wie,

ja, also

was ist eigentlich, kann ich sowas

wie ein Int-Typ überhaupt

irgendwie selber basteln?

Das geht ja jetzt in Python nicht, geht auch

in Java nicht. Aber in Swift

ging das natürlich, deswegen Swift, voll gut.

Da könnte man halt, kann man solche Typen halt tatsächlich

bis ganz runter selber

sozusagen als Library-Autor

halt auch haben und

selber definieren.

Und natürlich, also in gewisser Weise, da ist

schon das auch ein Punkt dabei. Und das ist

natürlich in Python vielleicht jetzt nicht so

einfach wie in anderen Sprachen.

Ja, das...

Aber so zum

Lösen von Problemen finde ich das auch

irgendwie schon sehr, sehr angenehm

im Vergleich zu allem anderen. Aber

kann auch sein, dass ich da einfach nur komisch bin und

das halt für mich funktioniert.

Die Interviewreihe, die du da gerade aufgemacht hast, die kann ich auch allgemein empfehlen

Da hatte ich letztens nämlich jemanden

Wie hieß der noch mal? Wie hieß der Interviewer?

Lex Friedman

Lex Friedman, genau

Und da hatten wir diesen einen Chip-Designer

Der ist auch extrem spannend, den sich anzunehmen

Das ist gerade so ein thematischer Querschlag

Aber ich glaube, die muss ich einfach mal loswerden

weil der hat mich dermaßen begeistert

wie hieß er denn

Lex

Friedman mit

er hat zu viele Sachen gemacht

oh ja

der macht eine ganze Menge

genau

wo ist er, wo ist er, wo ist er

Chipdesigner, Chipdesigner, Chipdesigner

Namen sind

Schall und Rauch.

Ja, manchmal macht er auch so ein bisschen komisch.

Also manchmal ist mir das auch, ich weiß nicht, es gibt ja so eine,

also ich würde das mal, also wenn man das so

versteht, also es ist halt auch

sehr amerikanisch, muss man sagen.

Und manchmal macht er auch einfach so etwas

seltsame Dinge, irgendwie so,

sagt dann, dass er jetzt nur noch Fleisch isst oder

keine Ahnung oder macht ganz viel mit

Cryptocurrency-Zeugs, was ja auch irgendwie

ein bisschen ist, aber

ja, aber es sind auch auf jeden Fall

super interessante Sachen dabei.

Genau, also hier Lex Friedman Nummer 70, Jim Keller

Ah, okay, gut

Jim Keller ist tatsächlich

einer der

also ich hab da gleich nach 10 Minuten

so ein bisschen so einen Man-Crush entwickelt

der ist so

intense

wie der da sitzt

und denkt und redet

und sein Minenspiel eigentlich gar nicht so richtig

präsent ist so richtig und dann doch so

ganz kleine Nuancen und

haut da Sachen raus zum Thema

Chip Design und der ist halt sozusagen

in den 80ern

ist der ins Chip Design eingestiegen

und hat so alles mitgemacht.

Der hat halt bei AMD und bei Apple und bei

Tesla und bei Intel gearbeitet

und ich habe jetzt so ein bisschen so persönlich

dieses Gefühl von

dieser Kampf zwischen AMD

und Intel, der wird

eigentlich nicht irgendwie da weit oben ausgetragen,

sondern die Frage ist nur, ob Jim gerade bei

AMD oder bei Intel ist.

Die Folge heißt übrigens Moore's Law.

Ja, genau.

Ja, also der war, der ist schon krass, der ist schon, der war richtig gut.

Ja, also ne, der Podcast kann man tatsächlich empfehlen, es gibt auch andere tolle Folgen, die man hören kann, mit Donald Knus oder Paul Krugmann sogar mal dabei gewesen und und und.

Es lohnt sich die auch auf YouTube zu gucken, es gibt Videos davon mit den Interviews, nicht nur als Podcast.

Und da ist, ja, die Niemieg ist, ja.

Die geht nach Norwegen.

Ja, ja.

Wenn man mal so durchscrollt.

Ja genau

Wo waren wir denn jetzt?

Wir wollten eigentlich ein Petra-Fall machen

Ja genau

Ja und

irgendwie gewisserweise

auch zu

Patterns hatte

was zu sagen und so

also Patterns sind ja auch immer so

es wird halt gesagt

wenn man Patterns braucht, dann hat die Sprache

eventuell einfach nicht

genug, also hat,

was ist das eigentlich?

Man zeichnet dafür, dass die Sprache halt etwas nicht kann,

was sie vielleicht können sollte und deswegen muss man halt

einen Pattern machen und

das kenne ich auch schon lange und

er fügte halt dann noch was

hinzu, was mir dann, wo ich dachte so,

oh ja, das stimmt, das ist ja auch eigentlich

so ein Problem, das ist nicht nur bei Patterns so,

sondern halt auch bei sowas wie,

gibt es eigentlich sowas wie eine Standardbibliothek

und das ist halt immer, das ist ein

ähnlicher Trade-off, also wenn du jetzt

irgendwie bei Python eine relativ große Standardbibliothek

hast, dann hat das natürlich eventuell den Vorteil,

dass du dir so etwas ersparst wie JavaScript, ja, die haben das

da halt nicht und dann kriegst du halt ein Pern.

Und das ist halt sozusagen ein Pattern, um halt

diese fehlende Standardbibliothek irgendwie

dann aufzufangen, sozusagen außerhalb von dem,

was die Sprache tatsächlich macht und das ist halt

so ein bisschen fies dann unter Umständen. Auf der anderen

Seite ist es natürlich auch so, dass es wieder ein Vorteil sein kann, weil wenn man jetzt

sich TypeScript anguckt oder so, wenn sich so ein

Type-System halt außerhalb der Sprache entwickeln kann, kannst du das natürlich deutlich

schneller tun, als wenn das immer nur alle 18 Monate oder jetzt alle

12 Monate updatable ist

mit dem Gedächtniskzyklus der Sprache. Also es ist nicht so einfach.

Und mit Patterns ist es halt irgendwie

ähnlich.

Wenn eine Sprache halt sehr, sehr viel kann, dann

braucht man eigentlich nicht so viele Patterns, weil

dann hat man einfach diese Probleme nicht.

Und auf der anderen Seite, wenn

ja,

gibt es einen Nachteil, wenn eine Sprache zu viele Features hat?

Naja gut,

dann ist man halt auch an die Sprache sehr

gebunden.

Eigentlich hat das keinen Nachteil.

Ich glaube, Patterns ist sozusagen

das war gerade aufgekommen,

da war ich glaube ich im Studium,

in die Hand nimmt, ist das in der IT sozusagen das, wo es alles mit angefangen hatte.

Und vielleicht kann man da noch kurz den einen Umweg gehen zu, Name, wie hieß er,

Steve Alexander?

Nee.

Alexander war Alexander.

Christopher Alexander.

Christopher Alexander war das, genau.

Er war ein Architekt und der hatte dieses Thema Python-Sprachen halt mal aufgegriffen

aufgegriffen und bzw. entwickelt, um sich städtebaulich so einem Gesamtkunstwerk anzunähern.

Um halt auf der einen Seite zu sagen, okay, Patterns sind Dinge, die immer wieder auftauchen,

die halt in leichten Variationen anwendbar sein müssen.

Und es ging ja nicht darum, dass Patterns, es sind ja Patterns und nicht Templates.

Also was ist das denn? Ist das sowas wie ein Mosaikbaustein-Ding, das man irgendwo reinstecken kann

und dann in alle Richtungen funktioniert?

Nee, eigentlich nicht.

Eigentlich ist es halt tatsächlich ein Entwurfsmuster,

wo du mehrere Dinge genannt bekommst drumherum.

Also sie haben da ein gewisses formales Schema aufgebaut.

Es ist ein Name und Klassifikation und Zweck und Synonyme und Motivation.

Und aber was eben tatsächlich interessant ist,

sind halt dann immer Hinweise zur Anwendbarkeit,

und

und der hat so ein ähnlicher Einsatz wie von diesem Muster und dann liefert dir das Muster zumindest schon mal einen Design Input von, also wenn du jetzt sowas in dieser Art machst, dann solltest du auf x, y, z achten und dann hängt da noch das und das und das dran.

und es ging nicht darum, sozusagen ein fertiges Stück Code, was man nur noch copy-pasted irgendwo reinzusetzen,

sondern zu sagen, na guck mal, es gibt zum Beispiel, wenn du das Problem hast, dass du Code dynamisiert auswählen können möchtest,

dann ist zum Beispiel das Strategy-Pattern eine mögliche Variante, das zu tun.

Das sieht dann so und so und so aus und da muss man auf das und das und das aufpassen und den Rest baust du dir jetzt selber zusammen.

Ja, das ist ein bisschen wie wenn ich sage, ich setze mich hin und schneide mir ein Kleid, dann habe ich da Entwurfsmuster, aber ich muss natürlich trotzdem noch messen, ob mein Bauch ein bisschen dicker ist, meine Beine ein bisschen länger und muss das dann halt anpassen.

Und da ging es tatsächlich dann darum, und das ist auch das, was der Christopher Alexander an der Stelle wollte, er wollte ja damit Leuten eine Auswahl von Mustern an die Hand geben, wo die Muster auch ineinander greifen und zusammenspielen.

und die Sprache der Verknüpfungen.

dieses, man muss es sich selber zurechtschneiden

für den eigenen Anwendungsfall.

Ansonsten hätte man das ja auch in der Library kippen können.

Das hätte man sagen können, das ist jetzt der einmal

fertige Code und

der Trick ist aber, das Muster auf einer Ebene

greifen, wo ich nicht vorher sagen kann,

ah, da braucht man eine Funktion für

oder da braucht man dieses Ding oder eine Klasse

oder sowas, sondern es ist häufig auch ein,

ja, wenn du folgende sieben Zeilen

dreimal geschrieben hast, dann sollst du mal darüber nachdenken,

ob du das vielleicht anders anordnen möchtest.

Aber das ist jetzt ja vielleicht nochmal interessant

für alle unsere Hörer, weil wir haben jetzt ja abstrakt

vielleicht irgendwie da mit angefangen,

was so Patterns vielleicht

so

konzeptuell sein sollten und vielleicht gehen wir

noch so ein bisschen in die konkretere Implementierung,

was es denn so gibt an

Sprachpatterns überhaupt und dass wir vielleicht die mal

erklären und ein bisschen

versuchen, wie man

das in Python vielleicht macht,

wenn man das macht,

wenn man die überhaupt braucht.

Ja genau,

also ich meine, die Muster, die sind ja

sozusagen allgemeingültig.

Das sind ja tatsächlich

sehr abstrakte Ideen,

die da existieren.

Fangen wir vielleicht mal mit Anfang an, was ist denn Strategie gesagt?

Ja, ich würde woanders anfangen, ich würde beim Singleton

anfangen. Ja, okay, fangen wir beim Singleton an.

Was ist denn Singleton?

Die mäßige, schöne Übersetzung ist das Einzelstück.

Ich mag es

einfach nicht, wenn.

Es gibt ja so ein paar Kategorien,

also Singleton gehört zu

den Mustern aus dem Bereich

Creational Patterns,

Also wie werden in einer objektorientierten Sprache Objekte erzeugt?

Da gibt es verschiedene Muster. Es gibt manchmal den Effekt, und gerade in Java ist das halt noch ein stärkerer Fall,

dass ja alles als alles muss eine Klasse sein.

Und manchmal brauchst du aber Code, wo es nur ein einziges Objekt zu geben darf.

Und dieses Objekt soll aber auch gut zugänglich sein.

und das kann zum Beispiel so was sein wie das Objekt, es gibt ein Python-Analogum dazu tatsächlich sogar,

das ist nämlich das Objekt, was den Logger in dieser Anwendung zum Beispiel repräsentiert.

Davon willst du nicht fünf Logger haben nachher, sondern willst halt irgendwie, wo ist denn hier die Log-Konfiguration,

mit dem Ding möchte ich jetzt reden, da soll jetzt bitte Log-Output rausgehen.

und da gibt es dann halt entsprechende Muster, wo man sagen kann, okay, wenn irgendwer die Klasse in die Hand kriegt und die nochmal neu instanziiert, dann dreht die sich um und gibt einfach statt ein neues Objekt zu machen, dir das eine erzeugte Objekt schon wieder zurück.

und dieses konkrete Singleton lässt sich aus Java so auf Python, du kannst es glaube ich

Codemäßig sogar so bauen, das hat aber nicht die gleichen Eigenschaften, weil die Sprache ja eine andere ist

und in Python gibt es dafür halt andere Möglichkeiten sowas zu machen, dass du zum Beispiel sagst, du hast einen Namespace

bei dir in deiner Anwendung, ein Modul, das heißt dann Log, man sollte es nicht Logging nennen, das geht gerne schief

wenn man die Standardbibliothek startiert. Das heißt vielleicht log und da drin gibt es eine

Klasse, das ist dann dein Logger und nach der Definition der Klasse würdest du gleich dieses

Objekt instanziieren. Wenn du willst, löscht du danach diese Klasse einfach aus dem Namespace

von dem Modul wieder raus. Dann kann auch keiner aus Versehen so eine zweite Instanz machen und

dann muss man wieder dazu sagen, naja Python als Sprache für Erwachsene, das stimmt halt so auch

und die Klasse aus dem Modul löscht, dann ist der Name zwar nicht mehr ansprechbar,

aber du kannst natürlich auf diesem singleton-Objekt wieder nach under underclass fragen,

dann hast du das Klassenobjekt, dann kannst du da wieder eine neue Instanz von machen.

So, jetzt kannst du halt hergehen und kannst, wenn du willst, in Python sagen,

also der, jetzt muss ich selber überlegen, welche Doppel-Unterscore-Methode da die richtige war,

nicht init, sondern was?

Create?

Nee.

New, genau.

Ich habe es zu lange nicht mehr in der Hand gehabt.

Ich merke, ich mache in letzter Zeit zu wenig Metaprogrammierung

in Python.

Du könntest aber under under new nehmen

und könntest dort sowas machen wie

wenn es

auf dem Klassenobjekt

schon ein bestimmtes Attribut gibt,

nämlich die Instanz selber

von dem Objekt, was du mit der Klasse erzeugt hast,

dann liefer einfach das zurück und ansonsten

mach einmal ein neues und ansonsten nie wieder.

Solche Meta-Aktionen kann man

damit machen. Die Frage ist nur immer

und was hat das Pattern für einen Kontext?

Es gab eine ganze Zeit lang, und das wurde so ein bisschen diesen Java-Programmierer-Schmieden,

die halt so viele Leute, wie möglich, die Java programmieren können sollten, rausgespuckt hatten,

so Ende der 90er und Anfang der Nullerjahre, die sind immer rausgekommen mit,

ich kann die Patterns, ich muss alles in Patterns denken.

und das ist aber in der Informatikausbildung selber ein Pattern, was immer wieder kommt,

dass die Leute irgendwie Werkzeuge in die Hand gedrückt kriegen und dann denken, ich muss alles mit diesen Werkzeugen ausdrücken.

Und eigentlich ist es aber umgekehrt, eigentlich ist es halt, du schreibst halt Code und wenn du die Patterns kennst,

dann merkst du vor deinem Auge plötzlich, ich baue hier etwas auf, das riecht wie so ein Singleton.

Dann sollte ich mir jetzt nochmal kurz Gedanken machen, was wir alles wissen über diese Form von Pattern

und ob ich jetzt bestimmte Dinge von Fehlerbehandlung, von bestimmten Edge Cases etc. nicht einfach alle gleich glatt ziehe,

weil ich weiß, wenn ich das jetzt so und so mache, dann habe ich das hier alles handwerklich ordentlich gemacht.

Und es ist aber ein Bottom-Up-Approach und gelehrt wird das Ganze häufig halt als Top-Down-Approach,

im Sinne von, du baust deine Anwendung nur noch aus Dingen zusammen, die diese Patterns sind.

Und das ist halt Quatsch. Du baust halt die Anwendung erstmal, wie du sie willst und wenn du feststellst,

und Jochen unterhalten sich über die Programmiersprache Python

das ist halt irgendwie fehlende Sprachfeatures

so ein bisschen relevant

weil tatsächlich

braucht man diese Patterns

vor allen Dingen in Sprachen

wo halt das

syntaktisch einen Unterschied macht, also wenn ich

zum Beispiel in C++ oder auch in Java

oder selbst in JavaScript

wenn ich da new sage, um ein neues

Objekt irgendwie

zu erzeugen

dann habe ich halt das Problem

also in Python ist es halt

ist ja sozusagen neues Objekt erzeugen

gar nicht syntaktisch zu unterscheiden von

einem Funktionsaufruf. Das sieht halt einfach genauso auf.

Und ich kann ja irgendwas zurückgeben.

Also ich muss ja jetzt, wenn ich ein neues Objekt

erzeuge, nicht irgendwie irgendwas new sagen,

sondern ich rufe halt eine Funktion auf

und dann habe ich halt ein neues Objekt. Aber die

könnte da halt auch was ganz anderes machen.

Auch ein Objekt von einer anderen

Klasse zurückgeben oder so.

Das geht halt in C++ nicht.

Wenn ich da sage new irgendwie diese Klasse,

dann kriege ich halt ein Objekt von dieser Klasse.

Also muss ich mir, wenn dann was anderes rauskommen soll,

halt überlegen, wie gehe ich denn jetzt damit um?

Und dann kriege ich halt irgendwie

FLs-Kaskaden in Konstruktoren und dann

irgendwann denke ich mir so, das sieht aber hässlich aus, was mache ich denn jetzt?

Und dann brauche ich halt Python.

Oder ein bisschen Gagge-Pile um die Ohren.

Und

das hat man in Python so

eigentlich, würde ich sagen, so viele der braucht man so nicht.

Also es gibt vielleicht, ich würde sagen, Ausnahme ist vielleicht

das Bilder-Pattern, das man halt auch in Python

vielleicht ganz gut verwenden kann.

Bitte noch erklären, was ist das Bilder-Pattern?

Bitte?

Also das Bilder-Pattern ist halt sozusagen, wenn man jetzt

nicht nur ein Objekt bauen möchte, sondern halt

eine ganze Menge von Objekten dann wird das halt unter Umst un Wenn ich das jetzt irgendwie muss ich halt einen Konstruktor machen der irgendwie riesig wird und ganz viele Argumente

oder so, das ist halt eventuell nicht so schön

ein gutes Beispiel dafür

ist halt

LXML hat da so

ein Ding, wie man sozusagen

XML-Dokumente zusammenbauen

kann, das ist halt quasi Bilderpattern

kann man sagen, also wenn man sich das mal angucken

will, da gibt es dann halt für jedes Tag

gibt es halt ein Objekt und dann kann man das halt ineinander schachteln und dann hat man

quasi, sieht das syntaktisch so ein bisschen aus, als würde man XML zusammenbauen und

hat dann aber tatsächlich eigentlich quasi

halt eine Reihe von Objekten zusammengebastelt.

Meistens reicht es aber, also das, wofür dann das Bilderpattern verwendet wird

in anderen Sprachen, in Python reicht es dann meistens irgendwie einfach

eine neue Klassenmethode an ein Objekt dran zu machen, die halt dann irgendwie Sachen zusammenbaut.

Das geht halt

Anderswo geht das halt nicht so gut

Dann muss man halt das

ein bisschen komplizierter machen, aber es gibt auch in Python Fälle

wo man das Pattern tatsächlich braucht

Und es ist halt schön das Pattern zu

kennen, auch wenn es halt nicht primär um

komplizierte Syntax geht

Hat das was mit Factory zu tun, weil das

Builder Pattern heißt?

Ja, also Factory Pattern würde ich sagen, braucht man fast nicht

Das ist genau so etwas

Da das irgendwie da

Funktionen First Class

Dinger sind in Python

gibt es eigentlich gar keine andere Zweifel.

Was ist denn das Factory Blatt? Dann fangen wir wieder so an.

Wir wollen ja auch ein bisschen erklären.

Ich weiß gar nicht,

ob ich das genau gut erklärt kriege.

Guckt irgendwas aus,

wird irgendwas fabriziert auf eine ähnliche Art

und Weise, irgendwas

generiert, was ähnliche Eigenschaften besitzt?

Ich weiß nicht.

Nee, es geht eigentlich eher darum, dass du deine Objektkonstruktion konfigurierbar machen möchtest.

Dass du nicht sagen möchtest, du hast halt nicht irgendwie einen Hammer und ich mache jetzt irgendwie einen New Hammer,

sondern du hättest gerne jetzt einen sehr speziellen Hammer mit einem möglichen, keine Ahnung,

so einem Stil, der so und so lang ist und keine Ahnung, der soll so und so schwer sein und weiß ich nicht.

und

ja,

jetzt ist halt die Frage, wie konfigurierst

du dieses Ding halt und wo man in Python halt

eine Funktion verwenden würde, musst du halt

in anderen Sprachen jetzt anfangen

sozusagen da Objekte ineinander

zu stapseln.

Und ja, aber ich kriege es jetzt auch,

weiß ich nicht genau, ob ich das so super erklärt kriege.

Ich habe mir das auch schon lange nicht mehr angeguckt.

Ja, man muss an der Stelle halt

auch

gucken, es geht

wieder um Syntax halt auch an der Stelle.

Das eine ist, du benutzt halt plötzlich keinen new operator mehr an der Stelle. Das geht weg, sondern du änderst halt den Aufruf eines traditionellen Konstruktors in halt eine ganz normale Funktion oder Methode und kannst halt tatsächlich auch unterschiedliche Semantiken haben.

also hier wird zum Beispiel gerade ein Beispiel aufgeführt von

hab eine Farbklasse und du willst jetzt eine neue Farbinstanz haben

und sagst einmal create from RGB oder create from HSV oder solche Sachen

das kannst du damit ein bisschen expliziter machen

speziell wenn du dann halt wirklich unterschiedliche Semantiken haben willst

oder das Ding noch 13 andere Dinge tun soll

oder eben gar kein new aufruft, sondern das Ding von woanders heranzerrt

Da sind Konstruktoren halt häufig einfach extrem begrenzt, was die Flexibilität angeht.

Und das ist tatsächlich in Python halt ein, naja, Init und Usen sind halt auch nur ganz normale Funktionen,

die kannst du parametrisieren und benutzen, wie du willst. Da ist Python halt einfach eine Ecke voraus gewesen.

Nichtsdestotrotz kann man halt noch was daraus lernen. Ich mache das auch gerne manchmal, dass ich Konstruktoren habe,

oder solche Factories haben, die eben dieses aus unterschiedlichen Kontexten rausinitialisieren.

Es ist in der Python-Bibliothek selber auch drin, wenn man sich DateTime zum Beispiel anguckt,

dann gibt es da mehrere, das sind dann entweder Klassen- oder Statischulmethoden,

die heißen dann irgendwie fromTimestamp oder from was auch immer,

um dann halt ein Objekt dieser Klasse zu erzeugen,

aber eben mit völlig anderen

Ansätzen

und der Code ist natürlich leichter zu strukturieren

als wenn du nur einen Konstruktor hättest

wo 23 Parameter drin sind, die sich

alle nicht auf den Füßen rumtreten dürfen

Ja

Ja, dann machen wir doch weiter

mit was für, würde ich sagen, Snickers

eigentlich hatten wir ja mit dem Singleton angefangen und mit den

verschiedenen Arten

Achso, ja, ja, genau, auch zu Singleton wollte ich auch noch kurz, genau

was ich meistens verwende oder was für meine

Anwendungsfälle, wo ich sowas habe, wie den Singleton,

meistens reicht es tatsächlich irgendwie

eine Variable in einem Modul.

Weil das ist ja, das Modul ist schon

Singleton irgendwie und wenn ich da halt

irgendwas anpacke, dann ist das halt überall

gleich, wenn ich das irgendwo

importiere. Es gibt

da so einen Pattern von

Alex Martley, wenn man tatsächlich sowas

braucht wie SharedState,

aber manchmal braucht man nicht unbedingt

immer die gleiche Instanz, sondern nur, dass sich alles

immer gleich irgendwie verhält und die gleichen

den gleichen State hält, da kann man das Borg-Pattern

verwenden. Das ist so ein bisschen ähnlich wie

ein Singleton. Wie das Borg-Pattern?

Das ist kein originales Gang of Four.

Nein, aber das ist halt sozusagen

irgendwie eine etwas Pythonischere Variante.

Ja, und es gibt dann natürlich auch noch die,

man kann tatsächlich auch so machen, dass es halt so

ist wie Singleton in anderen Sprachen, dann meistens

irgendwie muss man dann so Metaprogrammierung mit New

und keine Ahnung, ist aber dann schon nicht mehr so richtig einfach

und meistens, wie gesagt, also

meiner Erfahrung nach braucht man es eigentlich nicht.

Ja.

Ja, okay. Also was für Paths haben wir denn noch? Also ich kann jetzt natürlich die Liste hernehmen, aber wir haben jetzt Single-Ding gehabt, wir haben kurz Factory.

Es gibt noch zwei, die jetzt aus meiner Historie immer relevant waren. Das waren Proxys und Adapter. Da muss ich mal die ganz ollen Gammellen rausholen.

also SOAP 3 war damals tatsächlich also SOAP 2 und deren Nachfolger SOAP 4 und SOAP 5.

Wie bitte was?

Da gab es auch einen.

Bitte?

SOAP, genau.

Das ist der Open Source Urgroßvater der Applikationsserver.

Z-O-P-E, SOAP.

Achso, SOAP.

Ja, okay.

Ja, genau. Und das war ursprünglich ja so ein Through-the-Web-Entwicklungsumgebungstool, wo man halt nur durch einen Browser mit Python und so ein paar HTML-Template-Sprachen sich extrem schnell Webanwendungen zusammenbauen konnte.

Es hat einfach nichts, so richtig gar nichts mehr mit dem vorherigen Ding zu tun gehabt

Da war halt eine der Grundideen, dass es möglich sein sollte

Libraries und Anwendung oder Anwendungskomponenten, das nannte sich dann auch Komponentenarchitektur

So miteinander zu verheiraten, dass es eine zentrale Registry gibt, in der aufgezeichnet wird

wie man Dinge miteinander verbinden kann

also das war dann sehr stark Interface basiert

das ist jetzt auch was was in anderen Sprachen

stärker verankert ist als Python

und da hatten wir

extra eine Interface

Typ für entwickelt

mit dem du dann deklarieren konntest

das hier ist ein formales Interface, es muss folgende Methoden haben

die Methoden müssen folgende Parameter haben

also Interface ist ja ein anderes Designpattern

ne Interface ist noch nicht mal so richtig

ein Designpattern, Interface ist

kommt eher aus dem

aufrufst, wenn du dir irgendwas

übergibst, musst du dir halt sagen, was das denn ist.

Du kannst dir nicht einfach irgendwas übergeben.

Und wenn du jetzt

Objekte

unterschiedlicher Art da reintun willst,

dann müssen sie zumindest

vom gleichen Interface erben, sonst geht das

halt einfach nicht. Du kannst halt, du könntest

zum Beispiel

sagen,

okay, ich habe hier irgendwie eine Methode, die

schreibt irgendwie, zum Beispiel, die lockt irgendwas

weg oder so.

Und ich gebe da jetzt irgendwas rein, aber

was du jetzt reingeben möchtest, ist einmal

vielleicht irgendein Log-File, in das reingeschrieben wird,

aber du möchtest vielleicht auch, dass das irgendwie

übers Netz in irgendein Socket geschrieben wird.

Und dann kannst du sagen, okay, Socket und mein

File haben beide ein File-like Interface

sozusagen, das sie implementieren

oder dann halt auch explizit davon erben,

wenn du das halt irgendwie so machen willst und

dann kannst du das halt dann

sozusagen, sagst du in der Methode

also ich habe hier, hätte

gern ein Ding, dass

das File-Interface

sozusagen

implementiert und

kannst dann sozusagen

darauf dann irgendwie write aufrufen oder so.

Die Menge der Methoden,

sozusagen, die man

da aufrufen kann, das ist halt das Interface.

Also die Idee ist,

der wichtige Unterschied ist, dass du

mit Interfaces halt

Implementation und Spezifikation voneinander

halt trennst.

Das heißt, ich habe eine abstrakte Vordefinition.

Ja, also

wir hatten es damals so gemacht, es gab einen speziellen

Klassentyp,

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Ducktyping

Das heißt, solange es sich so verhält, wie es soll, ist mir als Laufzeitumgebung völlig egal, was du reinstopfst. Das ist ja dann jetzt mit den Type Annotations kannst du da jetzt Laufzeitumgebungen nehmen, die das halt ein bisschen strenger behandeln und auch mit statischer Analyse schon mal versehen.

Aber da ging es uns tatsächlich mehr darum, wenn man solche Annotationen hat, dass man daraus dann auch den Vorteil zieht, dass ich sage, okay, ich definiere ein Interface für etwas und wenn ein Objekt ein Parameter eines bestimmten Typs erwartet oder ein Objekt erwartet, das ein bestimmtes Interface erfüllt,

und die Funktionen.

und dann konntest du in der Laufzeitumgebung vorher registrieren und sagen, ah, also, wenn jemand einen ILogger braucht und einen String bekommen hat, dann mach bitte folgendes und dann kommt da dieses Objekt raus.

Oder wenn eine Methode einen ILogger braucht und da kommt ein Socket raus, da wurde ein Socket übergeben, dann mach bitte das und geh dann weiter.

und da kannst du sozusagen immer wieder beliebige

Typtransformationen mitten reinsetzen

und hast dich dadurch flexibilisiert,

dass jemand anders plötzlich anfängt,

okay, ich gebe dir, liebes Programm,

jetzt plötzlich Objekte anderen Typs rein

und deklariere an der dritten Stelle,

wie diese Typtransformationen zu laufen haben

und dann kann ich plötzlich halt Anwendungen

auf Arten benutzen, die nie so vorgesehen waren.

Das hört sich nach großer Magie an.

Das war ein Haufen Magie,

da war ein Haufen Engineering drin,

um das auch schnell zu kriegen.

also das war wirklich so

wenn man bei Soap nachher in einer

ernsthaften Anwendung mal eine Seite aufgerufen

hatte, dann waren in einem Call bestimmt

eine halbe Million Adapter Calls drin

und die waren

aber auf C-Ebene halt so optimiert, das waren halt

nur ein paar Millisekunden, die dafür draufgingen, das war alles

extrem schnell

da wurde extrem viel Arbeit reingesteckt

und da gibt es wirklich

also da gibt es Architekturen, die wir

in Anwendung hatten, die waren extrem

interessant

Problem ist aber, die sind auch extrem

aufwendig zu pflegen.

Also da spielst du dann halt Informatik

wieder mit in der Klasse von

wir ziehen uns jetzt alle den Laborkittel an

und designen das jetzt hier ordentlich durch,

ansonsten fliegt uns das alles um die Ohren.

Da ist so ein iteratives Vorgehen

hat nur so

begrenzt getragen, weil du halt häufiger

recht große starre Refactorings hattest,

die du dann halt nehmen musstest.

Aber dieses Adapter-Pattern hat es

extrem flexibel gemacht.

Also das war schon

richtig gut.

und das zweite wo ich mich hier in Fanatismus und Rage vor euren Augen im Video begeben hatte,

war dann was da auch eine Rolle gespielt hat, waren sogenannte Proxy Patterns, dass also ein Objekt

anstelle eines Anderes irgendwo rein gereicht wird und er emuliert alle Attributzugriffe und alle

Funktionsaufrufe, macht irgendwas und reicht den Originalaufruf dann an das Originalobjekt halt

und dann hast du hier gleich

sowas wie eine Middleware

nur genau umgedreht, im Prinzip.

Du injectest das Ding

in was anderes rein.

Eine Middleware ist ja typischerweise was, was

in der Pipeline irgendwo drin sitzt

und du kannst aber halt beliebigem

anderen Code das Ding einfach unterjubeln.

Und das läuft dann durch diesen Code

mit durch. Und wie mache ich das?

Das ist relativ

easy. Also die Frage

ist immer, wann du bei Python

Also die ernsthaften Proxys, die wir hatten, waren dann Security Proxys.

Die waren in der Lage, anhand von Access Controls, einer relativ aufwendigen Architektur,

tatsächlich für jeden einzelnen Funktionsaufruf zu sagen, ob der zulässig ist oder nicht.

Ob dieser User mit den Rechten auf dem Objekt, das da aus der Datenbank kam,

wenn das Objekt dann auch noch zu dem Kunden gehört, da so, darf der jetzt diese Funktion aufrufen, ja oder nein.

das war halt eine sogenannte Subject Oriented Security

und das ist so ein Unterschied

heutzutage viele Systeme

haben nur

View Oriented

Security, dass du halt sagst, okay darf ich

jetzt diesen View anschauen oder nicht

und da war es aber tatsächlich so, dass wir

praktisch alle Objekte

die aus der

originalen

Factory mal rausgefallen

sind von, okay hier ist deine Datenbank

Connection oder sowas

die wurden in solche Security-Proxys eingepackt

und dann konntest du nachher wirklich für jeden einzelnen Attributzugriff

aussteuern, ob da jetzt Security

eingreifen soll und sagen soll, nee, User mit den

Permissions dürfen halt auf die Passwortfelder nicht zugreifen

und wenn du das in deinem Template-Code aber gemacht hast, dann ist aber

der ganze Request abgewürgt worden mit das jezu nicht

da musst du halt dann noch einen Check gegenbauen und sagen, ah

der darf das nicht, dann wird das Template ordentlich gerendert und ansonsten hast du

aber immer den Safety-Belt, das ist dein Framework

selbst wenn du Blödsinn im Code schreibst

du musst da nicht drüber nachdenken

darf ich jetzt hier das Passwort rausrendern oder nicht

es geht nicht raus, im schlimmsten Fall wird die Seite halt abgebrochen

und er sagt so hier ist nix

und die mussten wir

aber tatsächlich auf C-Ebene schreiben

um wirklich alles komplett unterbinden

zu können an Protokollen, die Python so kann

mit den Doppel-Underscore-Methoden

einen einfachen Proxy kannst du in Python

schreiben, indem du einfach nur sagst

das ist eine Klasse, die hat ein Init

da übergibst du das Objekt, was

und über die GetAttribute Protokolle

und dann kannst du über die GetAttribute Protokolle

dann halt sagen, aha hier versucht jemand gerade zuzugreifen auf folgendes Attribut

und jetzt kannst du ein bisschen Log-Output erzeugen

und danach halt das Original-Objekt mit genau diesem Objekt wieder aufrufen.

Und das ist der Vorteil bei Python, was diese Patterns angeht,

mit Python als protokollorientierter Sprache.

Du hast immer irgendwas, was keine spezielle Syntax braucht,

sondern du kannst in der Metaprogrammierung

immer diese Doppel-Underscore-Methoden

benutzen, um dann wieder

über das System selber zu reden.

Also dann Magic quasi direkt auf den Objekten

während die gebaut werden.

Jetzt müssten wir

im Podcast sozusagen ein bisschen Live-Coding machen, um

da...

An welcher Stelle das

injiziert werden soll. Wenn du jetzt sagst,

dass das schon gebaut wird, jetzt weißt du,

die Inlet ist dann quasi schon durch. Also der Konstruktor

ist quasi geschehen.

und dann habe ich ein fertiges Objekt.

Genau, das ist aber das Proxy-Objekt.

Also es hat aber doch erst ein

Proxy-Objekt gebaut und das dann quasi

die anderen In-Edit-Methoden erst aufruft

und währenddessen...

Du hast ein Proxy-Objekt, das kriegt das

Objekt, was du

hinter dem Proxy haben möchtest,

das reichst du dem rein.

Also, ich versuche es ein bisschen

bildlicher zu machen. Du hast ein Objekt

aus deiner Anwendung, zum Beispiel

den Datensatz von einer

Person aus der Datenbank als

Objekt. Class Person und die Instanz davon, die aus der Datenbank kam und jetzt mit den Daten

gefüllt wurde, die hast du vor dir. Person A. Person A. So. Und jetzt würdest du sagen, ich habe einen

Proxy, der loggt alle Zugriffe auf Attribute von Objekten mit. Das Ding weiß nichts von Personen,

Klassen oder irgendwas. Aber ich instanziere jetzt quasi den Proxy mit dem Objekt Person A.

mit dem Objekt Person A als Parameter.

Bei dem Proxy heißt dieses Objekt intern nur

Kontext zum Beispiel.

Das speichert der bei sich auf under under

Kontext zum Beispiel.

Wichtig ist under under, also auch hinten, damit es in private namespace kommt und so.

Und wenn jetzt

implementiert der Proxy noch eine zweite Methode,

wenn du es ganz einfach machst, nimmst du under under getAddr

under under.

Die wird ja immer dann getriggert, wenn jemand

auf ein Attribut zugreift, was nicht definiert ist.

Da der Proxy

selber kein Attribut hat, wird es immer

getriggert.

In dem Moment würde er dann

zum Beispiel ein Print machen von, ja,

hier wurde jetzt auf folgendes Attribut zugegriffen

und ruft dann

self.under under context under under

get attra

dieses Objekt auf.

Diese Attributnahme auf. Er reicht sozusagen

den Methodenaufruf 1 zu 1 weiter

und gibt es auch wieder zurück.

Und dieses Objekt kannst du jetzt jedem anderen,

der von Logging

keine Ahnung hat, einfach in die Hand drücken

und könntest damit zum Beispiel

tracen, wer ruft

denn hier auf diesem Objekt jetzt, wenn ich jetzt folgenden

Client-Code habe, eigentlich was auf.

Was wird da gemacht? Da könnte man auch einen Debugger bauen

oder sowas quasi. Kannst du dir einen Debugger mitbauen,

einen Flow-Debugger.

Genau.

Oder kannst du halt auch sozusagen,

ja genau, einen Debugger. Kannst du zum Beispiel auch was machen

mit, aha,

den Code da hinten kann ich nicht ändern,

weil der ist so irgendwie keine Ahnung wie, komme ich

nicht ran, aber

jetzt mache ich so ein Proxy-Objekt und wenn jemand

auf dem Proxy-Objekt die Methode A aufruft,

dann starte ich ein PDB.

Und das

ist dann ein Proxy, du wickelst

etwas ein

und gibst das eingewickelte Ding weiter mit dem

anderen, mit dem Original drin.

Da kann er quasi alles mitlesen, was der da

an Daten aus der Datenbank zieht.

Genau, also in Python kannst du, wie gesagt, es ist immer die Frage, diese Double-Under-Methoden, wenn du sagst, der andere kann alles an Python schreiben, was es gibt und du hast den Client-Code, der ist völlig unbekannt, dann musst du den auf C-Ebene schreiben, um wirklich sicher zu sein.

wenn du aber weißt, was der andere Code macht

dann kannst du Proxys auch rein in Python schreiben

es ist nur in Python

wenn jemand gegen dich arbeitet

mit deiner Metaprogrammierung

dann kommst du gegen das Gegenarbeiten

auch erst wieder an, wenn du weißt, wie er gegen dich arbeitet

damit kannst du keine Security bauen

aber du kannst halt

hilfreiche Dinge bauen

oder du kannst zum Beispiel

eine Proxy bauen, der alle Methodenaufrufe cached

und das Schöne ist, du kannst das dann halt machen für Objekte, die du selber nicht unter Kontrolle hast.

Also das ist sozusagen, du hast einmal die Objekte kommen von irgendwo, wo du den Code nicht ändern kannst

und du steckst in irgendwas rein, wo du auch nicht ändern kannst, was da passiert

und ein Proxy kann da an der Stelle halt dann plötzlich neue Fertigkeiten einführen,

die mit beiden Codebasen im Prinzip nichts zu tun hatten.

Ja, da gibt es verschiedene Magie mit dem Flow irgendwie was.

Genau, genau.

Okay, also das war der Proxy-Pattern.

Das ist ein ganz interessanter Pattern.

Ja, genau.

So eine Strategy ist halt auch was ganz Interessantes noch.

Vielleicht das wäre so eins, was ich reinbringen würde.

Aber Jochen, magst du vielleicht noch eins?

Ja, also zum Beispiel Fassade.

Das ist halt sozusagen wie, baut man eine API sozusagen,

wenn man eine komplizierte Geschichte

hat mit vielen Objekten oder so, dann

baut man davor halt

eine API, die

jetzt irgendwie einfacher zu bedienen ist.

Das ist auch etwas, was man häufig hat und

würde ich jetzt sagen, so in Python, was man

da ganz oft macht, ist ja eben

nicht das Pattern zu verwenden, sondern das halt irgendwie

in, dann da in

das PY zu schreiben sozusagen, was halt

exportiert werden soll und

quasi alles so umzuorganisieren,

dass es dann halt von außen gut aussieht.

Ja, genau.

ja.

Decorator sind in Python Sprachfeature

inzwischen.

Das war auch mal

ein separates Muster.

Aber ich meine,

Decorator-Pattern ist das nicht das, wo man

so etwas machen kann, wie wenn man aus einem

File liest, dann die Leerzeilen

wegschmeißen oder sowas?

Man rappt den Funktionsabruf und Input und Output

kann man dann immer modifizieren?

Nee, das ist ein Python-Decorator,

also das mit dem Add irgendwas drüber.

Ich meine, das Decorator-Pattern wäre ein bisschen anders.

Aber vielleicht höre ich mich auch quasi nicht mehr genau. Ich meinte, das wäre halt irgendwie sowas, dass du halt sozusagen tust halt so, als wäre das ein normales File, aber in Wirklichkeit schmeißt das Objekt, was du halt mit dem Deco-Hater-Pattern gebaut hast, halt intern sowas wie Leerteilen weg oder Dinge, die nicht gepasst werden können oder so.

und dann... Tatsächlich ist es gerade auch so ein bisschen

ähnlich zu dem Proxy,

wie wir es beschrieben haben. Da ist in Python

der Unterschied nicht so groß.

Ja, ja. Hier wird nochmal, also ich gucke

gerade immer so ein bisschen nochmal die Wiki-Seiten nebenbei

nach. Beim Decorator wird

nochmal explizit darauf hingewiesen,

dass man hier halt chainen kann.

Das kannst du im Proxy aber auch machen.

Dass du da mehrere hintereinander schaltest.

Ja.

Ja.

Ja.

und ansonsten

was mir noch, au,

letztens ist mir das aufgefallen,

Mysterium, ich weiß nicht in welcher Episode

wir das hatten, da habe ich mich irgendwann mal gewundert,

da dachte ich

zuerst, das muss irgendwann letztes Jahr gewesen sein,

ob das irgendwie eine Python 3.8 Neuerung gewesen

wäre oder so, ich weiß es nicht,

hat ja mit Listen von irgendwelchen Dingen zu tun, mit

Listen von Integers

und das war deutlich

kleiner, als ich das gedacht hätte.

Ich dachte so, hä,

komisch, warum,

also es braucht tatsächlich nur

irgendwie

8 Byte irgendwie

pro Integer.

Eigentlich hätte ich jetzt mit deutlich mehr gerechnet.

Weiß ich nicht, eher so

23 oder

weiß ich irgendwas.

Darum ist das so viel kleiner.

Und die Antwort darauf habe ich jetzt gefunden

und das ist eigentlich blöd, aber

ich weiß nicht, wisst ihr das zufällig? Oder hättet ihr eine Ahnung

gehabt, was das hätte sein können?

Also ich habe halt eine Liste gemacht mit

irgendwie, weiß ich nicht, 100 Millionen

Integers und das war halt dann bloß 800 MB im Hauptspeicher und ich hätte aber eigentlich erwartet,

dass es hätte deutlich mehr sein müssen.

Ich wäre ja die Redundanzen weggelassen.

Das, was da tatsächlich passiert ist, ist halt intern benutzer

Python-Interpreter auch ein Pattern, um halt Integers

und zwar nur kleine Integers sozusagen da Hauptspeicher

zu sparen. Das Pattern nennt man Flyweight

und die

Integer von 0 bis

255, glaube ich, sind halt

irgendwie immer die gleichen. Also man kriegt immer das gleiche

Integer sozusagen zu sehen

und deswegen ist das halt

im Hauptspeicher deutlich kleiner.

Das heißt,

es gibt halt sozusagen nur...

Ist ja auch eine Form von Singleton.

Es ist sehr ähnlich zu Singleton, genau.

Also eigentlich ist das halt für solche Dinge gedacht,

wie du hast halt,

wenn du jetzt

in einen Textprocessor

hast, so ein Programm, was sowas wie Word oder so, und wenn das jetzt

Buchstaben rendert, dann willst du halt nicht immer

quasi alles, was halt in

der Buchstabe ist halt ein Objekt, dann willst du nicht immer alles für jeden Buchstaben,

was da dran hängt, nochmal haben, sondern du willst es halt nur den Teil in dem

Buchstaben austauschen, der halt ausgetauscht werden soll, und der ganze Rest bleibt einfach immer gleich.

und genau, für sowas ist es eigentlich gedacht und

in Python wird es halt auch für Integers

verwendet und deswegen

ist halt, wenn man jetzt sagt

Liste von 100 Millionen

Integers, also für i in Range

weiß ich nicht, 100 Millionen,

aber dann sagt man halt irgendwie sowas wie 0 oder

5 oder so, dann ist das halt sehr klein,

aber wenn man sagt

nicht

0, sondern irgendwie

i, dann wird es plötzlich sehr groß.

Also dann hat man den Vorteil nicht mehr.

Aber genau, da hatte ich mich

irgendwann mal drüber gewundert und jetzt habe ich irgendwann zufällig gesehen, woran das lag.

In Python gibt es ja noch den Begriff in-turning für.

Das kann man dann auch ganz gut sehen, wenn man die Objekte dann mit einem Identitätsvergleich anguckt.

Dann sind es halt tatsächlich wirklich immer, dass das Is das Gleiche ist.

Und das gibt es bei Strings halt auch.

und Jochen unterhalten sich über die Programmiersprache Python

und die Programmiersprache Python.

und die Sprache, die wir unterstützen. Dann kannst du halt das lange LF so refaktorieren, dass du jeden Teil davon in eine eigene Funktion packst.

Und entweder legst du die alle nach einem bestimmten Schema benannt in eine Klasse, sagst also sozusagen class country address format

und die Methoden darauf sind dann entsprechend zum Beispiel die ISO-Codes von den Ländern.

Und wenn du dann für eine Adresse, die du hast, dann sowas formatieren möchtest,

dann kannst du sagen, so, dann schnappen wir uns die Klasse,

lesen von dem Objekt runter den ISO-Code von dem Land

und rufen dann die Methode auf, deren Namen dem ISO-Code entspricht.

Und dann kannst du natürlich dir auch überlegen, das muss ich ja nicht unbedingt auf einer Klasse machen,

und die Programmiersprache Python noch andere ISO reinzuschreiben die ich halt noch nicht kannte und mein Code ist dann in der Lage jede beliebige Art der Formatierung aufzurufen Oder jemand anderes kann auch hergehen und sagen hey ich definiere dein Format f italienische Adressen gef mir nicht also ich jetzt diesen DICT von IT mit meiner eigenen Methode

und der Code, der aber jetzt

das aufruft, der hat halt jetzt keine

hartcodierten

LFL-Zweige mehr, sondern

der macht immer bloß noch dieses Dictionary-Lookup von

ja, mit welcher Methode soll ich es denn formatieren?

Und das ist dann

halt eine sogenannte Strategy im Prinzip.

Hm.

Ja.

Und was ist ein Observer?

Hm.

Ich gucke nach.

Muss ich hier auch nachgucken.

Happy Google this for you.

Also ich glaube, das ist, ach doch, warte mal, das ist halt

wenn du benachrichtigt

werden möchtest, wenn sich

irgendwas geändert hat.

Also die, die den Bescheid sagt.

Ja, du

registrierst

dich halt irgendwo, quasi.

Also alle, die benachrichtigt werden möchten,

registrieren sich irgendwie und dann

rufst du da einmal

halt das auf

und dann werden halt alle benachrichtigt.

Ach Gott. Ja, es ist lange her,

dass ich mich damit beschäftigt habe.

Ja.

Das hat man im SOAP auch.

Das war das Event-Handling-System

tatsächlich.

Das ist halt ein...

Du hast zwei Enden,

die da mitspielen müssen. Das eine ist,

du möchtest halt,

dass zu bestimmten Ereignissen

in deiner Anwendung andere Leute

flexibel definieren können, was da alles noch

und die Programmiersprache Python.

zu registrieren oder Interface oder was immer, aber so im einfachsten Fall sagst du sowas wie

Event Trigger, Event Name und danach übergibst du zum Beispiel

irgendeinen eventspezifischen Payload, das ist in Python ja auch schön zu machen,

weil du ja auch mit Stern-Arcs, Stern-Stern-KW-Arcs arbeiten kannst, aber

du würdest halt sagen, so, Record Change als Event und hier ist das

Objekt, was sich geändert hat und jemand anders kann zu dem Event-System als

unparteiischen Dritten hingehen und sagen, so, hier ist eine Funktion, die übergebe

und die rufst du bitte immer dann auf, wenn ein Record Change Event kommt.

Das ist so wie man es in JavaScript ja auch kennt, dass man sagt, ich möchte bei einem Mausklick benachrichtigt werden,

ich möchte bei einem Tastaturanschlag benachrichtigt werden, so kann man das natürlich auch einfach für beliebige Dinge kodieren

und wichtig dabei ist halt, daraus baut man sich sein eigenes Framework.

In JavaScript ist über das DOM ja definiert, welche Events es da gibt und das ist eine Art, wie man sich selber solche Events halt bauen kann,

dass man sagt, okay, wenn auf einem Record-Objekt das Save aufgerufen wird, dann triggert der gleichzeitig noch, wenn sich tatsächlich was geändert hat, diesen Event

und dann kannst du zum Beispiel solche Dinge tun wie wieder loggen oder nochmal ein anderes Event mitschreiben oder keine Ahnung

Also quasi Event-Signale abfangen quasi

Kann man Signale abfangen, genau

Und wichtig ist halt an der Stelle, das ist in Python dann typischerweise eine synchrone Aktion

weil ja im Prinzip, du rufst die eine Funktion

auf, die ruft dann, die macht ein

sogenanntes, das nennt sich auch Method Dispatch

die ruft dann

auf, die guckt

danach, da kann man auch überlegen, darf es

mehrere Händler geben oder nur einen

in welcher Reihenfolge werden die aufgeführt, das sind dann so

wirklich so differenzierte

Betrachtungen von dem konkreten Eventsystem, was man

sich baut, oder

gibt es nur ein Bestmatch von, je nachdem

dass ich auch noch auf Typen von den Parametern

matche, sowas wie, ich will aufgerufen werden

beim Record Change, aber nur wenn der Record vom Typ Person war und solche Sachen.

Und dann kannst du halt solche Dinge machen wie

ein User setzt eine Bestellung ab und

ein anderer Code von dir, ein anderes Modul, ist zum Beispiel dafür da, eine E-Mail

rauszuschicken, wenn der User seine allererste Bestellung abschickt.

Ja, dann kannst du das halt als völlig komplex... Häufig geht es bei

diesen Sachen darum, wie kann ich Code so geschickt modularisieren,

dass ich halt später, wenn ich die Anwendung

umbaue, möglichst wenig umstricken

muss und mir selber auf den Füßen

stehe. Idealerweise kannst

du halt dann auch mit sowas wie FeatureFlex

ganze Module stilllegen und

das ergibt aber trotzdem noch eine konsistente Anwendung

und nicht, ah da musst du in der

Klasse die drei Zeilen da wegschmeißen, in der

Klasse die drei Zeilen, in der Klasse die drei Zeilen

sondern daraus kriegst du halt so eine

komponierbare Anwendungsarchitektur

im Prinzip nachher.

Mhm, okay.

Und auch da wichtig,

und die

und hier jetzt geht der Blumenstrauß auf von

wie könnte man das eigentlich alles bauen

und das heißt aber nicht, dass man das halt

jedes Mal ständig in der Vollausprägung baut

ich weiß, ich sage das jetzt zum dritten Mal, aber

ich habe auch gelernt, wenn man

Dinge zum siebten Mal sagt, dann hat die Hälfte

deutlich zum ersten Mal gehört

und das habe ich auch heute gelernt, weil du gerade

vom Blumenstrauß an Methoden sprachst, es gibt auch Welkeblumen

in Blumensträußen

ja genau, es gibt auch Welkeblumen

möchtest du Welke

möchtest du unter den Patterns Welkeblumen suchen

Ja, tatsächlich, du weißt ja nicht genau

was da stimmt, wenn du jetzt davon noch keine Ahnung

hast und die eben nicht durch

von vornherein verstehst, oh ja,

das ist das dies und jenes, sondern du versuchst

halt dich irgendwie an eine, ich sag mal,

clevere Architektur zu halten oder

eine, die du für clever hältst, vielleicht weil du es noch nicht verstehst

oder denkst, du müsstest halt in die Richtung

entwickeln, um möglichst

flexibel oder modular zu bleiben oder so

oder halt verschiedene Schnittstellen aufmachen

zu können, wenn du sie brauchst, dann

könnte sowas ja passieren, dass man eine

welke Blume baut, weil man da irgendwelchen Unsinn gebaut hat.

Also speziell halt,

das kommt dann eher aus dem Agilen, das

you ain't gonna need it.

Also ich finde halt, man sollte sich bei der Anwendungsmöglichkeit

extrem stark auf den, erst mal

auf den Inhalt der Anwendung

konzentrieren.

Und erst wenn man eine gewisse Menge

und Masse beisammen hat und überhaupt weiß, worum es

eigentlich geht und was man tut,

dann kann man irgendwie ans Gärtnern gehen und kann

gucken, okay, jetzt räumen wir hier mal auf. Also da ist

Python als Sprache natürlich auch wieder extrem gut

positioniert, weil

und die

und die Programmiersprache Python.

aber für mich ist das immer eine Sache, das geht erst am konkreten Objekt.

Ich kann mich nicht vorher hinsetzen und sagen, so, wir bauen jetzt ein neues Backup-System,

wir brauchen einen Observer.

Und ich glaube, was eben ganz wichtig ist, was bei den Patterns auch...

Also Yagni ist auch kein Pattern.

Persistency means having to say I'm sorry

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

Programmiersprache Python

und die

das einmal auf Platte geschrieben hast,

dann kannst du aber wissen, dass das

sich in 10 Jahren noch verfolgt.

Ja.

Ja, und wenn man das richtig gemacht hat, dann

hat man halt

sozusagen auch später noch großen Nutzen.

Der schöne Spruch da an der Stelle

ist ja immer irgendwie Daten,

also gute Daten altern wie Wein.

Das ist halt schön, wenn man irgendwie mehr gute Daten hat.

Schlechte wie Milch.

Ja, Applikationscode,

wenn man gesagt hat, Applikationscode altert wie Fisch.

Das ist halt

durchaus auch und so.

Jaja.

Ich glaube an der Stelle auch, das ist halt der handwerkliche

Teil Teil Teil Teil

und die Programmiersprache Python.

Client Code auf Attribute zugreift, jemals noch irgendwie sich dazwischen zu hängeln.

Das ist ein reiner Future Proofing Aspekt und ich sehe immer wieder Leute, die aus der

Java-Welt kommen, die in Python Code schreiben und dann für jedes Attribut eine Getter Setter

Methode schreiben und du siehst sofort, dass es Java und wenn man dir dann irgendwann erzählt,

nein, es gibt, du kannst im Nachhinein eine Property draus machen, kannst machen was du

und die Technik der Sprache.

transportiert, muss man schon immer noch mal extrem gut auf die Suche gehen von

hat es hier nicht irgendeine andere Mechanik in Python, die das schon

überflüssig macht. Wir haben die Dekoratoren,

wir haben die Konstrukturen, wir haben New, wir haben

Properties, die ganzen Sachen

und die erschlagen viele von diesen anderen Sachen halt.

Ja, okay.

Also die Gang of Four Patterns habt ihr schon einigermaßen einmal kurz eingekringelt und erwischt.

Würde ich sagen, ja.

Gibt es noch welche, über die ihr unbedingt reden möchtet?

Naja, es gibt dann auch so ein paar, die halt später dazugekommen sind, beziehungsweise Sachen, wo man nicht so klar sagen kann, ist das jetzt eigentlich ein Designpattern oder sowas wie, ja, MVC, weiß ich jetzt nicht, ist das ein Designpattern, eher nicht, ein bisschen größer, keine Ahnung.

Model View Controller.

Ja genau

Schwer zu sagen oder sowas wie

Model View Controllers

älter

Das war nicht

Also Model View selber

Das ist eine Anwendungsarchitektur

Die kam aber

82

83 irgendwann

Also die war halt schon

auch bevor man sich mit dem Begriff

Patterns auseinandergesetzt hatte an der Stelle

Ja kann gut sein

Ja, oder halt so etwas wie, ich glaube, die kam aber dann tatsächlich später, Datenbank, so ORM, so wie baue ich eigentlich ein ORM, also so was, eben Active Record oder halt Datamapper-Pattern, das ist halt auch so, tja, keine Ahnung, ob das Pattern sind oder

Was ist denn das hier schon wieder?

Ja, das ist halt die Frage, wie man sozusagen die Übersetzung macht zwischen Sachen, die jetzt in der Datenbank, vor allem in den relationalen Datenbanken liegen und halt Objekten in Python beispielsweise. Das sind halt diese beiden unterschiedlichen Dinge. Also Active Record ist halt das, was Django macht oder halt auch Ruby und Rails und Data Mapper ist halt das, was SQL Alchemy macht.

Und was ist der Unterschied?

und Jochen unterhalten sich über die Programmiersprache Python

Dann fangst du noch mit

XS Record an, Jochen?

Ja, also da ist es halt so, dass quasi

jedes Objekt

repräsentiert halt eine Zeile in der Datenbank

und die Attribute sind halt die

Spalten.

Wenn man halt

Dinge aus der Datenbank holt, dann hat man

halt eine Liste von diesen Objekten und

wenn man die Attribute ändert, dann speichert das halt

die, kann man halt sagen, auf dem Objekt, auf der Zeile

halt, speichert das und dann

geht das halt zurück in die Datenbank und

ja.

Genau, so sieht das halt ungefähr aus und normalerweise hat man eine Klasse, die definiert, welche Spalten es in dieser Tabelle gibt.

also du hast pro Tabelle

eine Klasse

und die

Spalten sind halt Attribute auf dieser

Klasse, die halt so ein bisschen

diese Deskriptoren-Geschichte

ein bisschen eigenartig

definiert sind und

dann kann man halt auch aus diesen

Klassen die Tabellen direkt erzeugen

auch die sozusagen

ja

Relationen zwischen den Tabellen sind halt

in den Attributen enthalten

das heißt ich kann halt wenn ich mir so

diese Tabellen

hindefiniert habe, halt auch komplett

mein Datenbankschema aus den Dingern

erzeugen.

Immer wenn einzelne Sachen

passieren sollen auf einer Zeile, dann sind das

halt

Methoden auf dieser Klasse.

Eine einzelne Instanz ist

eben eine konkrete Zeile

und wenn etwas alle Sachen betreffen soll

oder viele Zeilen, dann sind das halt

sogenannte Model Manager,

die dann halt irgendwie eine ganze Reihe von Sachen updaten oder halt

irgendwie

eine Reihe von Zeilen löschen

und so kann man das dann halt aufteilen, alle Methoden, die irgendwie auf einer einzelnen Zeile was machen sollen

gehen halt in die Klasse und alle Methoden, die halt auf vielen Sachen

was machen, gehen halt in den Manager auch, die jetzt irgendwas filtern oder so

und dann, ja, genau, so funktioniert es ungefähr

Und jetzt kommt SQL-IDEMY

Ja, Datamapper

Genau, ich habe jetzt

erst mal wieder die Active Record Sache

angeguckt und das Interessante bei Active Record ist ja,

dass du relativ klar

Tabelle und Klasse aufeinander

mappst und beim

Datamapper ist es ja so, du entkoppelst es

komplett und die

Objekte müssen halt, also beim Active Record

hat zum Beispiel die Klasse

gerne irgendwie eine Save-Methode

wo du sagen kannst, ich ändere

ein paar Attribute und dann kannst du irgendwie Save

aufrufen und dann ist die irgendwie in der Datenbank

das ist zumindest das klassische Pattern dafür

wie es bei Django jetzt gerade aussieht, weiß ich nicht

Ja, ja, doch, ist genauso

Und bei SQL Alchemist ist es so, dass im Prinzip

deine Klassen von der Datenbank

überhaupt nichts wissen

Es gibt

einen deklarativen Stil, bei dem du tatsächlich

dann wieder innerhalb, da kannst du wieder sagen

doch, die Klasse weiß was davon, weil du es halt

eng aneinander koppeln möchtest, um solche

Effekte zu haben, wie, dass du deine Datenbank

anhand deiner Klassendefinition

halt ableiten kannst, aber im Prinzip

und die

und ich beschreibe

Klassen und jetzt beschreibe ich, wie diese Tabellen auf Klassen gemappt werden.

Und da können halt auch alles mögliche reinspielen, dass irgendwelche Attribute

über komplexere Queries erst zustande kommen und dass da irgendwelche komplexen

Relationen zu sind und etc. Und SQL Alchemy bricht das auch

extrem abstrakt runter, dass du halt mit den Objekten nativ arbeitest, ohne

irgendwie über die Datenbank nachzudenken.

Und dann

baut der sich und du brauchst kein separates, wenn du viele Aktionen machst, kannst du auch einfach auf 100 Objekten rumrechnen

und er fasst das nach hinten automatisch in die optimierten SQL-Statements zum Beispiel zusammen,

dass er weiß, okay, der Herr hat hier 100 Objekte angefasst, jetzt machen wir ein großes Update-Statement,

das irgendwie einmal sinnvoll aussieht, bumm, anstatt halt dann die eher naiveren Varianten von,

okay, jedes Mal safe drücken ist jedes Mal einmal zur Datenbank laufen und speichern drücken oder so.

und da ist es halt einfach viel, viel flexibler, wenn du das Datenbankmodell entkoppeln möchtest.

Das ist zum Beispiel auch dann, wenn du konfrontiert wirst mit,

ich habe hier eine fertige Datenbank, die besteht seit 20 Jahren, die muss jetzt hier irgendwie mal rein.

Und dann kannst du mit dem Data Mapper...

Blala, es ist Zeit fürs Bett.

Dann kannst du mit dem Data Mapper Pattern nämlich beliebige Transformationen machen,

um zu sagen, okay die Datenbank

sieht aus wie Kraut und Rüben, aber ich habe

vorne ein ordentliches Object Model dran

so und bei

SQL Alchemy ist das Ganze sozusagen

wie heißt es denn da so schön

auf 11 gedreht

da ist es so richtig laut

da sind die Abstraktionen so gut gemacht

und die haben sich so viel Mühe gegeben was Performance angeht

das ist so ein Zeug von

du machst komplexere Abfragen und er weiß

okay wenn ich das jetzt mache

dann lade ich schon mal die nächsten Relations mit

und falte irgendwie die Relation-Objekte

schon mal in die originale

Seqquery mit rein, damit ich nur einmal einen großen

Bulk-Transfer am Anfang habe, anstatt

nachher bei jedem Attributzugriff nochmal zur

Datenbank zu laufen oder so. Und das

kannst du da extrem genau aussteuern.

Das hat ein Django-Dynamit, oder?

Ja, in Django ist

das, aber da gibt es das auch.

Das werden halt die Sachen,

also das, was man halt nicht

will, das droht bei Active Record

natürlich ist, dass wenn du jetzt

zum Beispiel irgendwie

und Jochen unterhalten sich über die Programmiersprache Python

N plus 1 Queries

gegen die Datenbank

und das ist natürlich extrem

fies und ein Haufen Performance-Probleme

kommen genau deswegen, aber also in Django

sagt man dann halt Select Related

genau, dann zieht es die

oder Prefetch Related

für N zu M

Relationen und so, also das geht auch alles

Machst du das am Model oder musst du das

an der Query machen? Das machst du an der

Query. Genau, bei SQL

Alchemy kannst du das im Prinzip modellieren

da kannst du halt diese ganzen Relationen

alle ausdefinieren

auch so richtig mit

Vor- und Rückreferenzen will ich die

irgendwie als Listen oder Dicks kriegen

oder als Attribute oder

so ein Zeug und kannst dann halt sagen

die Richtung, die machst du bitte als Eagerload

und die bitte nicht und folgende 10 Attribute

bitte im Eagerload wieder rauslassen

und das kannst du ja so alles zurecht tunen

damit du halt dann möglichst dummen

konkreten Query-Code schreiben kannst

der über so ein Zeug nicht mehr nachdenkt

ja, interessant

und du kannst bei SQL Alchemy auch sehr dynamisch

die haben halt auch eine voll getrennte Schicht

zwischen ich hab erstmal dieses Object

Mapping Ding und dann hat

der nochmal eine komplette Abstraktion über SQL

drüber, das heißt der kann dann halt die ganzen SQL

Dialekte halt auch noch

nach unten, der hat im Prinzip einmal SQL

in Form von diesem Builder Pattern

ja du kannst auch sagen

ich hätte gerne eine Query, also Query

Klammer auf von folgendem

gemappten Objekt und dann

Punkt

und er baut dir dann nachher tatsächlich einen für die Datenbank, die du eigentlich hast, also Postgres oder MySQL, ein syntaktisch korrektes und optimiertes Query halt auf, unter Berücksichtigung von allem, was er über diese Mapper weiß, was er gleich noch als Eager Load oder nicht machen soll.

und du kannst halt mittendrin immer wieder die Ebenen wechseln.

Du kannst irgendwie im Object Mapping Teil sein,

drei Zeichen dann von diesen generativen, also dann irgendeine Query mit dem generativen SQL machen,

da dann aber wieder gemappte Objekte reinstecken

und der kriegt das immer so vor und zurück und vor und zurück.

Hat halt das Problem, wenn es, also es tut sehr selten nicht,

aber man muss sich halt dann schon relativ viel mit,

schon gut mit dem relationalen Datenmodell auskennen,

um mit dieser Komplexität dann auch umgehen zu können.

weil wenn es dir dann mal um die Ohren fliegt

dann kommen da halt auch Fehler raus mit so

was will der jetzt von mir

ja

naja

wir haben das in Projekten

eingesetzt wo es halt teilweise um richtig richtig große

Datenmengen ging und da dann

halt wirklich an diesen Stellen

alle Stellschrauben zu haben

um das gerade zu ziehen

das ist halt dann in dem Moment extrem

viel wert

und umgekehrt das Active Record

wiederum, du fängst halt an

und hast sofort was, was du präsentieren kannst.

Das entwickelt sich halt sehr schnell.

Das ist halt super.

Ja, und dann, ich meine,

das geht bei SQL Alchemy

auch nicht. Man kann ja auch immer noch

auf rohes SQL zurückfallen,

wenn man irgendwas Spezielles

machen muss.

Ja.

Haben wir

alle Patterns durch, tatsächlich?

Also, du wolltest auch irgendwas zu Datenbanken sagen.

Ich habe da gestern noch so ein Solid-Modell

oder sowas.

Ja, achso, nee, das ist nicht Datman, aber das ist auch so genau, ja, ich weiß nicht, ob das Patterns sind, das ist eher so, was sollte man, wenn man Dinge macht, sowieso beachten vielleicht. Das ist halt auch so eine ganz bekannte Geschichte. Ich weiß gar nicht, ob man es unter Pattern Design Prinzipien, ja, ja.

Was ist das denn?

Ja, das ist

auch etwas, was, es gibt ja dieses

Buch Clean Code von

Robert Martin

und Uncle Bob.

Gibt es das auch in Python?

Das ist, nee, das ist

die ganze, das ist über uns,

ich meine, ehrlich gesagt, ich bin ja ein bisschen

peinlich berührt, wenn ich dann irgendwie so

Observer-Pattern, keine Ahnung, habe ich

schon mal gehört oder so. Bei den meisten

Patterns ist es so, ich habe die schon mal gesehen, vielleicht irgendwann

mal oder auch mal, aber so

wirklich viel zu tun habe ich mit denen ja eigentlich

nicht. Also dieses ganze Thema

kommt eigentlich eher aus so ein bisschen anderen Ecke

der Softwareentwicklung.

Und während das jetzt bei

so Java-Geschichten oder so halt so ist,

eben, da ist also für Juniorstellen

irgendwie, wenn man sich da,

wenn man da in Vorstellungsgesprächen ist, dann

wird halt erwartet, dass man die alle kennt und

ja,

das wäre dann schon sehr fein, wenn man sagt, also

ich habe keine Ahnung, was das eigentlich ist.

Aber ja, suche ich mal ja gerne Java.

Ja, das

Interessante ist auch, man kann

das Zeug ja im Alltag eben nicht so benutzen

wie bei jeder Zeile

Code, die ich schreibe, gehe ich nochmal alle

mir bekannten Patterns und Prinzipien durch, ob ich

die jetzt ja nicht verletze. So funktioniert

es halt nicht. Du willst ja, und deswegen

ist Pattern, glaube ich, auch für unsere Kognition

eigentlich ganz interessant. Du willst aber,

dass dein Gehirn eine ausreichende Menge von

so einem Zeug so dran trainiert hat,

dass wenn da irgendwie die roten Warnlämpchen angehen,

du halt weißt, Moment, jetzt mal nochmal

nachdenken, warum geht das hier schief?

Damit du dann halt wenigstens weißt, wo du googeln musst.

Ich habe über Solid jetzt gerade nochmal schnell drüber geguckt

Oh, das ist aber schon ganz schön alte Schule teilweise

Also wenn ich halt Liskov Substitution höre, dann so

Oh ja, das Akademikerherz

Das ist das L in Solid, ja, das Liskov Substitution

Ja, also es ist halt auch alles relativ alte Geschichte

und das macht halt in diesem Kontext von so statisch typisierten Programmiersprachen

macht das auch alles gewisserweise

schon Sinn, also durchaus

und auch mehr Sinn halt, vielleicht als bei Python,

weil da viele Dinge einfach automatisch

erfüllt sind. Also eben, ich würde sagen,

ja, ich würde, Lischkows

Substitution Principle?

Nee, das ist ein Designthema, das musst du selber

als Programmierer richtig umsetzen.

Das ist Typtheorie

und das ist die Aussage, dass

Objekte

in einem Programm, also aller Programm

Code, der Objekte verwendet, also mit Objekten arbeitet,

sollte immer in der Lage sein, alle Subtypen

dieser Objekte zu akzeptieren, ohne die Korrektheit des Programms zu verletzen.

Genau, also ich würde jetzt mal so als konkretes Beispiel

wäre jetzt für mich sowas wie, man macht eine Vorschleife über

Mitarbeiter und wenn man jetzt in der Vorschleife

so Fallunterscheidungen macht, also nehmen wir an, man hat eine Typarchie,

und Jochen unterhalten sich über die Programmiersprache Python

machen wir aber folgende Ausnahmegeschichten.

Wenn wir jetzt zum Beispiel Gehalt auszahlen wollen,

wir rufen nicht einfach Gehaltauszahlen-Methode

auf, sondern wir sagen nochmal,

okay, wir machen Speziallogik,

je nachdem, was das für ein Typ ist.

Du weißt schon, dass der Senior Vice President

Facility Management ein ziemlich stiller Witz ist.

Wieso?

Das ist voll wichtig.

Also dann hätte man sozusagen,

aus meiner Perspektive, hätte man jetzt

eben Lischkows Substitution

Principle verletzt, weil eben

der Code nicht

funktioniert, unabhängig davon,

was das für ein Typ ist,

sondern weil man da noch überprüft wird. Ja, noch nicht so ganz.

Also Spezialfälle

zu erlauben ist ja kein Problem,

es muss bloß die Korrektheit gewährleistet sein. Aber

Beispiel, wenn man zum Beispiel sagt,

der

und

Korrektheit ist tatsächlich auch immer eine spannende Frage

von, das gehört

für mich auch dazu, im Sinne von, erfüllt tatsächlich

auch nachher für den User was Sinnvolles.

und du sagst zum Beispiel, alle Mitarbeiter müssen eine private Telefonnummer haben

und bei den CEOs legt man dann fest, da ist wie immer 0, weil die privaten Nummern der CEOs werden nicht rausgegeben

und das würde einem Subtyp entsprechen, dann hättest du halt in dem Moment das verletzt,

im Sinne von, ja jetzt machen wir hier mal für Weihnachten die Telefonliste der Mitarbeiter fertig

und machen die Secret Centers für hier und da und den kannst du anrufen, um noch ein bisschen was abzufragen

und plötzlich kommen bei den CEOs halt da keine Telefonnummern raus.

Also ja, nee, das war jetzt halt kaputt.

Und das ist eine Designanforderung nicht von dem Client Code, der damit arbeitet,

das ist eine Designanforderung von Objekten, von Unterobjekten, von Unterklassen, von Subklassen.

Dass eine Subklasse den Raum der Möglichkeiten erweitern, aber nicht einstellen.

darf.

Okay, das ist L.

Jetzt haben wir noch S-O-I-D.

Das würde ich gerne verschieben.

Ich habe vorhin schon

meinen Zungenbrecher

gehabt.

Wir haben heute etwas Zeit.

Wir haben relativ gut zeitig angefangen.

Mit dem Nachteil, dass meine

Technik heute ein bisschen...

Du hast inzwischen für dich alleine geredet.

Ja, und auch bis wir zum Reden gekommen sind, dann weil irgendwie hier

alle gegen mich gearbeitet haben.

Wir machen das einfach zu selten, wir müssen das häufiger machen.

Das stimmt.

Sehr gerne. Wie gesagt, von meiner Seite

immer gerne. Wir müssen einfach immer

sofort den nächsten Termin ansetzen.

Ja, das machen wir.

Schön, dass ihr aber alle wieder eingeschaltet habt heute.

Ja, genau. An der Stelle müssen wir uns eigentlich auch entschuldigen.

Wir haben den letzten Monat irgendwie verbasselt, aber ich meine,

es war viel zu tun und so.

Ja, es war viel zu tun und zwar ein bisschen sehr...

Ja, eigentlich wollten wir noch

2 aufnehmen, da ist wieder was ausgefallen und so.

Die Termin-Findungs-

Koordinationsschwierigkeiten kommen noch

ihr Ugriges dazu. Ja, wir geloben Besserung,

das kriegen wir auch schon irgendwie hin.

Genau, nee, dann am besten,

ja, wir haben ja auch schon echt viel

Zeug gemacht, dann verschieben wir das mal solid,

das ist ein gutes Thema.

Ja, und halt auch noch so diverse

Architektur-Patterns, halt so Repository-Pattern,

Unit of Work, weiß ich nicht.

Es gibt da ein schönes Buch, das wäre dann schon sozusagen

Vorbereitung aufs nächste Mal. CosmicPython.com

.com.

Ich glaube, das heißt dann auch tatsächlich, wenn man es als Buch kauft,

also kann man da online lesen.

Ja es ist halt auch Architectural Patterns for Python oder irgendwie sowas Ist von dem na wie hei er noch Der auch Obey the Testing

Code geschrieben hat.

Und einem anderen.

Verdammt. Okay.

Weiß nicht mehr genau.

Da kann ich eigentlich auch sofort

nachgucken.

Percival.

Percival.

Kosmos hat sich

opposite auf Chaos und Gregory.

Aha, Kosmos ist die Opposite of Chaos.

Ja, das kannte ich noch nicht und das sieht aber tatsächlich gut aus.

Das sind so tatsächlich die Patterns, die ich auch kenne, die in Python gerne kommen.

Unit of Work ist so ein SQL-Meeting, auch Event-Driven.

Und MessageBus klingt gut, Commands klingt gut.

Dependency Injection ist super.

Das klingt interessant, das kommt in die Leseliste.

Super, dann haben wir auf jeden Fall auch noch eine Menge Stoff für den nächsten, für den zweiten Teil.

Ja, wir haben einige Teil-Dateien noch offen übrigens.

Ja, ja, Async muss wir auch unbedingt nochmal dran.

Ja, vielen Dank, dass du wieder da warst, Christian, Conny.

Danke, dass ich dir bei sein durfte.

Na klar.

Und schön, dass ihr eingeschaltet habt.

Und gute Nacht, guten Morgen, guten Abend und so weiter.

Bis zum nächsten Mal.

Bis dann.

Tschüss.

Ciao, ciao.