Threading in Python 3
-
- User
- Beiträge: 49
- Registriert: Mittwoch 22. September 2021, 14:01
Hallo liebe Community
ich habe in Python 3 eine Klasse geschrieben (mit Getter und Setter) diese hab ich in einem anderen Thread ausgeführt (mit _thread ) aber wie kann ich diesen Thread via setter noch nachträglich Parameter übergeben, also nach dem ebendieser Thread gestartet ist ?
Über Rückmeldung würde ich mich sehr freuen.
ich habe in Python 3 eine Klasse geschrieben (mit Getter und Setter) diese hab ich in einem anderen Thread ausgeführt (mit _thread ) aber wie kann ich diesen Thread via setter noch nachträglich Parameter übergeben, also nach dem ebendieser Thread gestartet ist ?
Über Rückmeldung würde ich mich sehr freuen.
_thread darf nicht nicht benutzen, das erkennt man am Unterstrich.
Daten dürfen nicht in unterschiedlichen Threads verändert werden, dafür gibt es passende Datenstrukturen, wie Events, Queues, etc.
Was in Deinem Fall richtig wäre, können wir nicht sagen, weil der Kontext und Code fehlen.
Daten dürfen nicht in unterschiedlichen Threads verändert werden, dafür gibt es passende Datenstrukturen, wie Events, Queues, etc.
Was in Deinem Fall richtig wäre, können wir nicht sagen, weil der Kontext und Code fehlen.
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Du solltest weder Setter und Getter noch _thread verwenden. Namen mit führendem Unterstrich bedeuten in Python: Implementierungsdetail, wer das verwendet, tut das auf eigene Gefahr. Geich im ersten Absatz der Dokumentation zu _thread steht: "The threading module provides an easier to use and higher-level threading API built on top of this module." Das solltest du verwenden. Da im Inhaltsverzeichnis der Dokumentation zur Standardbibliothek threading mehrere Einträge über _thread steht, frage ich mich, warum soviele Anfänger die Dokumentation von unten nach oben (d.h. von hinten nach vorne) zu lesen scheinen.
Und was Getter und Setter angeht: Das macht man in Python nicht. Python ist nicht Java. Wer Java programmieren will, soll Java programmieren, nicht Python.
Daten an laufende Threads übergibt man am einfachsten mittels einer queue.Queue. Dann braucht man sich auch keine Sorgen um konkurrierende Schreibzugriffe zu machen.
Und was Getter und Setter angeht: Das macht man in Python nicht. Python ist nicht Java. Wer Java programmieren will, soll Java programmieren, nicht Python.
Daten an laufende Threads übergibt man am einfachsten mittels einer queue.Queue. Dann braucht man sich auch keine Sorgen um konkurrierende Schreibzugriffe zu machen.
In specifications, Murphy's Law supersedes Ohm's.
-
- User
- Beiträge: 49
- Registriert: Mittwoch 22. September 2021, 14:01
In dem Buch https://www.springer.com/de/book/9783658264963 wird aber geschrieben das man mit Getter und Setter Arbeiten soll wenn man Python zum OOP verwendet will.pillmuncher hat geschrieben: ↑Mittwoch 13. Oktober 2021, 14:51
Und was Getter und Setter angeht: Das macht man in Python nicht. Python ist nicht Java. Wer Java programmieren will, soll Java programmieren, nicht Python.
Und Getter setter gibt es nicht nur in Java sondern auch in C# usw.
-
- User
- Beiträge: 49
- Registriert: Mittwoch 22. September 2021, 14:01
und mit Queue kann man ein einen bereits laufenden Thread Daten übergeben ?!pillmuncher hat geschrieben: ↑Mittwoch 13. Oktober 2021, 14:51
Daten an laufende Threads übergibt man am einfachsten mittels einer queue.Queue. Dann braucht man sich auch keine Sorgen um konkurrierende Schreibzugriffe zu machen.
Zuletzt geändert von PythonCodingFun am Mittwoch 13. Oktober 2021, 15:41, insgesamt 1-mal geändert.
-
- User
- Beiträge: 49
- Registriert: Mittwoch 22. September 2021, 14:01
Ich will einen weiteren Thread aufmachen der die Datenbank trigger ausgibt, dazu verwende ich die Lib psycopg [url]https://www..org/docs/advanced.html#asynchronous-notifications[/url]
Zuletzt geändert von PythonCodingFun am Mittwoch 13. Oktober 2021, 15:22, insgesamt 1-mal geändert.
Es gibt eine erstaunlich grosse Anzahl schlechter Werke ueber Python. Das scheint eines davon zu sein. Es ist seit *Jahrzehnten* bekannt, dass getter/setter in Python nicht idiomatisch sind. Wer das nicht weiss, hat offensichtlich bestenfalls oberflaechliche Kenntnisse in Python. Die Vorschaukapitel auf der Webseite bestaetigen diese Vermutung.
Was deine eigentliche Frage angeht: ja, man kann die Daten uebergeben, aber nicht, ohne Code und dessen Ablauf umzuschreiben. So ein Message-Passing kann ja nicht einfach per magischer Fernwirkung funktionieren, das muss schon einprogrammiert werden.
Was deine eigentliche Frage angeht: ja, man kann die Daten uebergeben, aber nicht, ohne Code und dessen Ablauf umzuschreiben. So ein Message-Passing kann ja nicht einfach per magischer Fernwirkung funktionieren, das muss schon einprogrammiert werden.
-
- User
- Beiträge: 49
- Registriert: Mittwoch 22. September 2021, 14:01
Also ganz ähnlich zu dem Beispiel https://www.psycopg.org/docs/advanced.h ... ifications hab ich auch eine Endlosschleife und ich wollte diese Schleife halt stoppen/beenden (dachte mit Getter/setter) und wollte argumente übergeben die dies bezwecken. Nur das die Funktionalität in einem anderen Thread läuft, und ich will den Thread nicht hart killen oder der gleichen, sondern "sanft" beenden.
Gibt es eine gute Ideen/Ansätze wie man das realisieren kann ?
Gibt es eine gute Ideen/Ansätze wie man das realisieren kann ?
Wenn es nur um ein simples boolsches "running" geht, kannst du das auch einfach via Attribut machen. Also sowas:
Ja, ganz strenggenommen muss man ein threading.Event oder sowas benutzen, aber da wir nunmal in CPython das GIL haben, mache ich das ueblicherweise ohne.
Code: Alles auswählen
class NotificationHandler:
def __init__(self):
self.running = True
t = threading.Thread(target=self._loop)
t.start()
def _loop(self):
while self.running:
# tu was
notification_handler = NotificationHandler()
time.sleep(10)
notification_handler.running = False
-
- User
- Beiträge: 49
- Registriert: Mittwoch 22. September 2021, 14:01
Dumme Frage bitte nicht böse sein : Was ist Cpython ? Ist das dass klassische "Pure" Python ?!
und warum sleep ?
Ich bin nicht "boese". Eher verzweifelt. Ist es wirklich so schwer, sich einen Begriff, den man nicht kennt, einfach mal kurz zu ergoogeln? Das beantwortet dann innerhalb von nur den ersten zwei Suchergebnissen schon in der Vorschau von Google diese Frage mit "ja". Du hast mehr Zeit gebraucht, das als Frage zu formulieren.
Das sleep steht nur als "mach was im Programm und beende den Thread spaeter" da.
Das sleep steht nur als "mach was im Programm und beende den Thread spaeter" da.
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Der Autor von dem Buch hat ein Jahr vor „Python lernen in abgeschlossenen Lerneinheiten“ ein Buch mit dem Titel „Java lernen in abgeschlossenen Lerneinheiten“ geschrieben. Und oh Wunder die Bücher sind gleich aufgebaut, enthalten viel gemeinsamen Text, und die gleichen Beispiele. Der Autor hat einfach mehr oder weniger Java durch Python ersetzt, ohne Python wirklich zu kennen/können, denn das sieht alles sehr nach Java und so gar nicht nach Python aus.
Aus den Beispielen die man sich auf der Springer-Seite anschauen kann, wieder mal der blanke Horror:
`getPerson()` gibt es im Beispiel im Java-Buch auch, entsprechend mit ``return this;``. Was der Quatsch soll, wird da auch nicht erklärt. Also die Methode kann weg.
`__anzahl` ist ein globaler und nutzloser Wert, kann auch weg. Würde man auch in Java nicht machen.
``private`` gibt es in Python nicht, und ``protected`` auch nicht. Es gibt öffentliche und nicht-öffentliche Attribute über die Konvention *einen* führenden Unterstrich vor nicht-öffentliche Namen zu setzen. Weshalb das `_thread`-Modul nicht verwendet werden sollte, denn das ist nicht für den öffentlichen Gebrauch.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Und dieses Zeichenketten und Werte zusammengestückel mit ``+`` (und ggf. `str()`) macht man in Python auch nicht. Dafür gibt es f-Zeichenkettenliterale. Bleibt also das hier:
So sieht `Adresse` im Buch aus:
Zu dem was zu `Person` zu sagen war, kommen hier noch die Abkürzungen bei den Namen hinzu, wobei `str` blöderweise schon für den `str`-Datentyp verwendet wird. So etwas sollte man nicht machen, weil das verwirrend ist, und man so in der `__init__()` dann auch `str` gar nicht mehr verwenden kann. Es erzeugt auch unnötig Aufwand beim Lesen wenn die Namen der Argument nicht den Namen der Attribute entsprechen, denen sie dann zugewiesen werden.
Die Strasse hat ein triviales Getter/Setter-Paar. Damit ist das de fakto öffentlich, also würde man in Python einfach direkt auf das Attribut zugreifen.
Bei der Postleitzahl ist es nicht ganz so trivial, weil dort eine Bereichsprüfung im Setter steckt. Das würde man in Python durch ein Property lösen. Und dann auch so, dass man den Test nur *einmal* im Code haben muss, und nicht zweimal. Codewiederholungen sollte man vermeiden (auch in Java und anderen Programmiersprachen), weil das unnötige Arbeit macht und fehleranfällig ist, weil man immer alle Kopien synchron halten muss.
Die Bereichsüberprüfung der Postleitzahl lässt sich in Python lesbarer über die Verkettung der Vergleichsoperatoren schreiben. Und statt eine Textausgabe zu machen oder geräuschlos den Wert ganz einfach nicht zu setzen, wenn er ausserhalb der Grenzen ist, würde man hier eine Ausnahme auslösen. Würde man auch in Java machen, das ist aber aus dem Java-Buch so übernommen.
In Python sähe die Adress-Klasse so aus:
Und sie wäre wahrscheinlich in der gleichen Datei, also im gleichen Modul wie `Person`. Denn eine Datei pro Klasse hat der Autor wohl auch von Java übernommen.
Aus den Beispielen die man sich auf der Springer-Seite anschauen kann, wieder mal der blanke Horror:
Code: Alles auswählen
class Person:
__anzahl = 0
def __init__(self, name, vorname, adresse):
self.__name = name
self.__vorname = vorname
self.__adresse = adresse
Person.__anzahl = Person.__anzahl + 1
def getAnschrift(self):
return self.__vorname + " " + self.__name + ", " + \
self.__adresse.getAdresse()
def getPerson(self):
return self
@staticmethod
def getAnzahl():
return Person.__anzahl
`__anzahl` ist ein globaler und nutzloser Wert, kann auch weg. Würde man auch in Java nicht machen.
``private`` gibt es in Python nicht, und ``protected`` auch nicht. Es gibt öffentliche und nicht-öffentliche Attribute über die Konvention *einen* führenden Unterstrich vor nicht-öffentliche Namen zu setzen. Weshalb das `_thread`-Modul nicht verwendet werden sollte, denn das ist nicht für den öffentlichen Gebrauch.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Und dieses Zeichenketten und Werte zusammengestückel mit ``+`` (und ggf. `str()`) macht man in Python auch nicht. Dafür gibt es f-Zeichenkettenliterale. Bleibt also das hier:
Code: Alles auswählen
class Person:
def __init__(self, name, vorname, adresse):
self._name = name
self._vorname = vorname
self._adresse = adresse
def get_anschrift(self):
return f"{self._vorname} {self._name}, {self._adresse.get_adresse()}"
Code: Alles auswählen
class Adresse:
def __init__(self, str, nr, plz, ort):
self.__strasse = str
self.__nummer = nr
self.__wohnort = ort
if (plz >= 10000) and (plz <= 99999):
self.__postleitzahl = plz
else:
print("Falscher Postleitzahlwert")
def getAdresse(self):
return self.__strasse + " " + str(self.__nummer) + ", " + \
str(self.__postleitzahl) + " " + self.__wohnort
def getStrasse(self):
return self.__strasse
def getPlz(self):
return self.__postleitzahl
def setStrasse(self, str):
self.__strasse = str
def setPlz(self, plz):
if (plz >= 10000) and (plz <= 99999):
self.__postleitzahl = plz
Die Strasse hat ein triviales Getter/Setter-Paar. Damit ist das de fakto öffentlich, also würde man in Python einfach direkt auf das Attribut zugreifen.
Bei der Postleitzahl ist es nicht ganz so trivial, weil dort eine Bereichsprüfung im Setter steckt. Das würde man in Python durch ein Property lösen. Und dann auch so, dass man den Test nur *einmal* im Code haben muss, und nicht zweimal. Codewiederholungen sollte man vermeiden (auch in Java und anderen Programmiersprachen), weil das unnötige Arbeit macht und fehleranfällig ist, weil man immer alle Kopien synchron halten muss.
Die Bereichsüberprüfung der Postleitzahl lässt sich in Python lesbarer über die Verkettung der Vergleichsoperatoren schreiben. Und statt eine Textausgabe zu machen oder geräuschlos den Wert ganz einfach nicht zu setzen, wenn er ausserhalb der Grenzen ist, würde man hier eine Ausnahme auslösen. Würde man auch in Java machen, das ist aber aus dem Java-Buch so übernommen.
In Python sähe die Adress-Klasse so aus:
Code: Alles auswählen
class Adresse:
def __init__(self, strasse, nummer, postleitzahl, wohnort):
self.strasse = strasse
self._nummer = nummer
self._postleitzahl = None
self.postleitzahl = postleitzahl
self._wohnort = wohnort
@property
def postleitzahl(self):
return self._postleitzahl
@postleitzahl.setter
def postleitzahl(self, postleitzahl):
if not 10_000 <= postleitzahl <= 99_999:
raise ValueError(f"Postleitzahl {postleitzahl!r} ungültig")
self._postleitzahl = postleitzahl
def get_adresse(self):
return (
f"{self.strasse} {self._nummer},"
f" {self.postleitzahl} {self._wohnort}"
)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Bei einem `getPerson` in einer `Person`-Klasse würde ich ganz stark vermuten, dass der Autor auch Java nicht kann.
Und Postleitzahlen hat er anscheinend auch noch nie gesehen, zum Beispiel 01067 für Dresden. Oder hat die Post da etwa was falsch gemacht und mehr als vier Millionen Menschen ungültige Postleitzahlen zugeteilt‽
Und Postleitzahlen hat er anscheinend auch noch nie gesehen, zum Beispiel 01067 für Dresden. Oder hat die Post da etwa was falsch gemacht und mehr als vier Millionen Menschen ungültige Postleitzahlen zugeteilt‽
-
- User
- Beiträge: 49
- Registriert: Mittwoch 22. September 2021, 14:01
Dann sagen die Leute, Bücher von großen Verlagen sind immer besser, als das was so im Internet steht
Da ich, ein Angfänger in Python, dachte mir so hey ein Prof. der ein Buch in einem großen Verlag schreibt, toll das was drin steh kann ja nicht verkehrt sein^^
So also bevor ich auf den Deckel bekomm (wegen getter oder setter) dann bitte eine Email an den Autor
Da ich, ein Angfänger in Python, dachte mir so hey ein Prof. der ein Buch in einem großen Verlag schreibt, toll das was drin steh kann ja nicht verkehrt sein^^
So also bevor ich auf den Deckel bekomm (wegen getter oder setter) dann bitte eine Email an den Autor
Zuletzt geändert von PythonCodingFun am Mittwoch 13. Oktober 2021, 19:30, insgesamt 2-mal geändert.
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@narpfel: Beim Java-Buch sind mir die statischen ``anzahl``-Attribute negativ aufgefallen und bei einem `Kreis`-Beispiel ist eine hässliche Asymmetrie bei `getMittelpunkt()` das ein Array aus zwei Zahlen zurückgibt, und `setMittelpunkt()` das zwei einzelne Zahlen als Argumente nimmt. Das Beispiel ist dann genau so nach Python übertragen.
``enum`` in Java und das `enum`-Modul in Python sind in beiden Büchern kurz vor Ende und die Beispiele nutzen jeweils nicht, das diese Typen deutlich mächtiger sind, als beispielsweise ``enum`` in C. Und selbst *das*, dass man jeder Konstanten auch einen numerischen Wert geben kann, werden in den Beispielen bei beiden Büchern nicht genutzt. Hier der Horror in Python:
Schlimmster Fehler ist das Vergleichen des Namens mit Zeichenketten. Genau damit man nicht irgendeine Zeichenkette vergleichen kann, sondern das ein eigener Datentyp ist, statt das man sich da einfache Konstanten definiert, ist ja gerade der Witz von `Enum`-Typen. Ebenfalls falsch, weil gefährlich ist das ``else`` am Ende. Wenn jemand auf die Idee käme da noch `Note.ungenuegend` hinzuzufügen mit dem Wert 6, würde dafür auch der Wert 5 ausgegeben werden. Wenn man den Vergleich so machen würde, wie das eigentlich gedacht ist, und sich an die Namenskonventionen haltend, würde das so aussehen:
Letztlich natürlich völliger Unsinn diesen ganzen Code zu schreiben, weil man den Wert der Konstante ja von der Konstante selbst abfragen kann:
Das Java-Beispiel sieht so aus:
In Java hat jeder Enum-Wert eine Ordnungszahl, auf deren Grundlage man hier den Notenwert ganz einfach berechnen kann:
Falls man den Zusammenhang zwischen Ordnungszahl und Notenwert stärker an den Aufzählungstyp binden/darin kapseln möchte, kann man dem ``enum``-Typ eine Getter-Methode dafür verpassen:
Als letztes reguläres Kapitel im Python-Buch ist sind „Dictionaries“ ganz kurz angerissen, sonst werden nur Listen verwendet. Und teilweise als Arrays bezeichnet, und auch mal mit 0en gefüllt, um dann diese 0en durch einzelne Zuweisungen durch `Person`- oder `Adresse`-Objekte ersetzt. An der Stelle möchte man als Python-Programmierer gerne das (zu leichte) Buch nach dem Autor werfen… Im Java-Buch kommen gar keine Datenstrukturen jenseits von Arrays vor. Nicht mal Interfaces werden in dem Java-Buch erwähnt! Generics schon mal gar nicht. Irgendwie hören beide Bücher auf bevor alle wichtigen Grundlagen behandelt wurden.
``enum`` in Java und das `enum`-Modul in Python sind in beiden Büchern kurz vor Ende und die Beispiele nutzen jeweils nicht, das diese Typen deutlich mächtiger sind, als beispielsweise ``enum`` in C. Und selbst *das*, dass man jeder Konstanten auch einen numerischen Wert geben kann, werden in den Beispielen bei beiden Büchern nicht genutzt. Hier der Horror in Python:
Code: Alles auswählen
import enum
class Note(enum.Enum):
sehr_gut = 1
gut = 2
befriedigend = 3
ausreichend = 4
mangelhaft = 5
print("Anzahl der Elemente:", len(Note))
for note in Note:
if note.name == "sehr_gut":
wert = 1
elif note.name == "gut":
wert = 2
elif note.name == "befriedigend":
wert = 3
elif note.name == "ausreichend":
wert = 4
else:
wert = 5
print(note, ": Name =", note.name, "=", wert)
Code: Alles auswählen
class Note(enum.Enum):
SEHR_GUT = 1
GUT = 2
BEFRIEDIGEND = 3
AUSREICHEND = 4
MANGELHAFT = 5
print("Anzahl der Elemente:", len(Note))
for note in Note:
if note is Note.SEHR_GUT:
wert = 1
elif note is Note.GUT:
wert = 2
elif note is Note.BEFRIEDIGEND:
wert = 3
elif note is Note.AUSREICHEND:
wert = 4
elif note is Note.MANGELHAFT:
wert = 5
else:
assert False, f"unbekannte Note {note!r}"
print(note, ": Name =", note.name, "=", wert)
Code: Alles auswählen
class Note(enum.Enum):
SEHR_GUT = 1
GUT = 2
BEFRIEDIGEND = 3
AUSREICHEND = 4
MANGELHAFT = 5
print("Anzahl der Elemente:", len(Note))
for note in Note:
print(note, ": Name =", note.name, "=", note.value)
Code: Alles auswählen
public class Test {
enum Note { sehr_gut, gut, befriedigend, ausreichend, mangelhaft };
public static void main(String[] args)
{
System.out.printf("Anzahl der Noten: %d\n", Note.values().length);
for (Note note: Note.values())
{
int wert = 0;
switch (note)
{
case sehr_gut: wert = 1; break;
case gut: wert = 2; break;
case befriedigend: wert = 3; break;
case ausreichend: wert = 4; break;
case mangelhaft: wert = 5; break;
}
System.out.printf("%s = %d\n", note, wert);
}
}
}
Code: Alles auswählen
public final class Test {
private Test() {}
enum Note { sehr_gut, gut, befriedigend, ausreichend, mangelhaft }
public static void main(String[] args)
{
System.out.printf("Anzahl der Noten: %d\n", Note.values().length);
for (var note: Note.values()) {
System.out.printf("%s = %d\n", note, note.ordinal() + 1);
}
}
}
Code: Alles auswählen
public final class Test {
private Test() {}
enum Note {
sehr_gut, gut, befriedigend, ausreichend, mangelhaft;
public int getWert() {
return ordinal() + 1;
}
}
public static void main(String[] args)
{
System.out.printf("Anzahl der Noten: %d\n", Note.values().length);
for (var note: Note.values()) {
System.out.printf("%s = %d\n", note, note.getWert());
}
}
}
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Mein Favorit bis jetzt ist `RegAusdruck4.py`:
Immerhin werden da keine Strings mit `+` zusammengebaut.
Code: Alles auswählen
import re
public class Zeichenkette
{
public static ArrayList<String[]> findMuster(String s, String r)
{
ArrayList<String[]> liste = new ArrayList<String[]>();
Matcher m = Pattern.compile(r).matcher(s);
while(m.find())
{
String elem[] = {m.group(), String.valueOf(m.start()), String.valueOf(m.end())};
liste.add(elem);
}
return liste;
}
public static void main(String[] args)
{
String s = "234 3323 22123 12312343 2312312312345";
ArrayList<String[]> liste = findMuster(s, "(123)+");
for(String elem[] : liste)
System.out.printf("%s: (%s - %s)\n", elem[0], elem[1], elem[2]);
}
}
- __blackjack__
- User
- Beiträge: 13100
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@narpfel: Wo ist das denn her? Ich habe hier die 2. Auflage von dem Buch, da steht das so:
Was hier blöd ist, ist das `reg` und `pattern` genau falsch herum benannt sind. Naja, und das man die Abkürzung `regex` vielleicht nicht noch mal mit `reg` abkürzen sollte.
Und kleiner Schönheitsfehler: In der Liste würde ich das als Tupel speichern und nicht als Liste.
Aber hey, im Java-Buch gibt es ja doch Beispiele von Datenstrukturen, sogar mit Generics. Den Kritikpunkt muss ich dann also zurückziehen. Wobei sich das ganze anscheinend auf `ArrayList<T>` beschränkt.
Code: Alles auswählen
import re
# ------------ Eingabe ------------
# 1. Zeichenkette
text = "02123 12343 2312312312345"
# 2. Regulärer Ausdruck
reg = r"(123)+"
# ----------- Berechnung ----------
pattern = re.compile(reg)
liste = [[m.start(), m.end(), m.group()] for m in pattern.finditer(text)]
# --------------- Ausgabe ---------
print(liste)
Und kleiner Schönheitsfehler: In der Liste würde ich das als Tupel speichern und nicht als Liste.
Aber hey, im Java-Buch gibt es ja doch Beispiele von Datenstrukturen, sogar mit Generics. Den Kritikpunkt muss ich dann also zurückziehen. Wobei sich das ganze anscheinend auf `ArrayList<T>` beschränkt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman