Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

konstante Lists, Dictionaries

17 views
Skip to first unread message

Markus Schaaf

unread,
Dec 22, 2023, 2:32:41 PM12/22/23
to
Hallo,

habe heute ewig nach einem "unmöglichen" Fehler gesucht, weil ich
nicht gemerkt hatte, dass ein Dictionary von verschiedenen
Coroutinen modifiziert wird. In typisierten Sprachen würde man
der Coroutine eine konstante Referenz übergeben. Gibt's in Python
Methoden, sich vor solchen Fehlern zu schützen, ohne eine tiefe
Kopie anzulegen? (Oder vielleicht ist das gar nicht so schlimm?)

MfG

Peter J. Holzer

unread,
Dec 22, 2023, 3:01:20 PM12/22/23
to
On 2023-12-22 19:32, Markus Schaaf <msc...@elaboris.de> wrote:
> habe heute ewig nach einem "unmöglichen" Fehler gesucht, weil ich
> nicht gemerkt hatte, dass ein Dictionary von verschiedenen
> Coroutinen modifiziert wird. In typisierten Sprachen würde man
> der Coroutine eine konstante Referenz übergeben.

"In typisierten Sprachen" scheint mir unzulässig allgemein zu sein.
Wirlich in allen typisierten Sprachen? Und was ist überhaupt eine
"konstante Referenz"? Immutable soll ja wohl nicht die Referenz sein,
sondern das, worauf die Referenz zeigt.

> Gibt's in Python Methoden, sich vor solchen Fehlern zu schützen, ohne
> eine tiefe Kopie anzulegen? (Oder vielleicht ist das gar nicht so
> schlimm?)

Speziell für dict gibt es einen PEP für frozendict und offenbar auch
eine Referenzimplementation auf PyPI.

Wenn Dein Objekt nicht allgemein immutable sein soll, sondern nur für
manche Routinen, könntest Du denen ein Proxy-Objekt übergeben, das nur
lesende Zugriffe auf das Originalobjekt durchreicht (Hmm, das müsste man
eigentlich ziemlich generisch schreiben können),

hp

Stefan Schwarzer

unread,
Dec 22, 2023, 3:31:15 PM12/22/23
to
On 2023-12-22 20:32, Markus Schaaf wrote:
> habe heute ewig nach einem "unmöglichen" Fehler gesucht, weil ich
> nicht gemerkt hatte, dass ein Dictionary von verschiedenen
> Coroutinen modifiziert wird.

Vor sowas schützt Python in der Tat schlecht.

> In typisierten Sprachen würde man
> der Coroutine eine konstante Referenz übergeben.

Python ist auch "typisiert", aber das Typ-System gibt es nicht
her, Änderungen zu kontrollieren. ;-)

> Gibt's in Python
> Methoden, sich vor solchen Fehlern zu schützen, ohne eine tiefe
> Kopie anzulegen? (Oder vielleicht ist das gar nicht so schlimm?)

Ein paar bunt gemischte spontane Gedanken dazu ... :-)

- Ob tiefe Kopien ein Problem für dein Programm und die darin
verarbeiteten Daten sind, musst du ausprobieren. Bei nicht zu
riesigen Datenmengen und häufigen Kopien kann es gutgehen.

- Versuch, im Design die Konstellation, dass ein Objekt von
verschiedenen Stellen geändert wird, von vornherein möglichst
zu vermeiden. Ok, das ist zugegebenermaßen sehr schwammig und
es hängt von deinem Programm ab, ob sich das gut umsetzen
lässt.

- Ich versuche, in-place-Änderungen möglichst zu vermeiden und
stattdessen modifizierte Objekte zurückzugeben. Sowas ist eher
in der Funktionalen Programmierung üblich, klappt aber auch oft
in Python einigermaßen erträglich. Je nachdem, was du für Daten
hast und wie dein Programmfluss ist, kann das aber auch darauf
hinauslaufen, dass du viele tiefe Kopien erzeugst, was ein
Problem sein _kann_ (siehe oben).

- Recherchiere zu sogenannten persistenten Datenstrukturen. Die
funktionieren so, dass bei einer Änderung ein neues Objekt mit
den Änderungen erzeugt wird und das ursprüngliche Objekt
unverändert bleibt. Anders als bei Python-Listen oder
-Dictionaries hängt die Zeit für ein solches "funktionales
Update" nicht (wesentlich) von der Größe der Datenstruktur ab.

Ich habe bei einer Suche zum Beispiel
https://github.com/tobgu/pyrsistent gefunden, kann aber nicht
einschätzen, inwieweit das in dein Design passt. Im
Zweifelsfall würde ich erst mal versuchen, das Problem mit
"Python-Standard-Designs" zu lösen.

In dem Zusammenhang würde mich interessieren, wer von euch
Erfahrungen mit solchen Datenstrukturen/Bibliotheken in Python
hat und wie gut das für euch funktioniert hat.

- Python hat, anders als zum Beispiel Rust, kein explizites
Ownership-System, aber du kannst dir trotzdem beim Designen
überlegen, welches Objekt der Owner eines bestimmten Objekts
sein soll.

Ich denke, um konkretere Ratschläge zu bekommen, müsstest du
deinen Code zeigen beziehungsweise die "konkurrierenden"
Code-Teile genauer beschreiben.

Davon abgesehen interessiert mich, wie andere Entwickler:innen
mit dieser Problematik umgehen. Was habt ihr für Ansätze
ausprobiert und was waren eure Erfahrungen?

Viele Grüße
Stefan

Markus Schaaf

unread,
Dec 22, 2023, 4:31:45 PM12/22/23
to
Am 22.12.23 um 21:01 schrieb Peter J. Holzer:

> Speziell für dict gibt es einen PEP für frozendict und offenbar auch
> eine Referenzimplementation auf PyPI.
>
> Wenn Dein Objekt nicht allgemein immutable sein soll, sondern nur für
> manche Routinen, könntest Du denen ein Proxy-Objekt übergeben, das nur
> lesende Zugriffe auf das Originalobjekt durchreicht (Hmm, das müsste man
> eigentlich ziemlich generisch schreiben können),

Danke. Sind beides gute Hinweise.

Markus Schaaf

unread,
Dec 22, 2023, 4:47:06 PM12/22/23
to
Am 22.12.23 um 21:25 schrieb Stefan Schwarzer:

> - Versuch, im Design die Konstellation, dass ein Objekt von
> verschiedenen Stellen geändert wird, von vornherein möglichst
> zu vermeiden. Ok, das ist zugegebenermaßen sehr schwammig und
> es hängt von deinem Programm ab, ob sich das gut umsetzen
> lässt.

Das mache ich ja. Ich nutze sonst viel C++. Und da ist es
beliebt, sich "kleine" Fehler vom Compiler melden zu lassen. Das
ist kein Fetisch, sondern die Einsicht, dass Menschen dumme
kleine Fehler machen.

> - Ich versuche, in-place-Änderungen möglichst zu vermeiden und
> stattdessen modifizierte Objekte zurückzugeben.

Das scheint mir die richtige Vorgehensweise für Python zu sein.

> Ich denke, um konkretere Ratschläge zu bekommen, müsstest du
> deinen Code zeigen beziehungsweise die "konkurrierenden"
> Code-Teile genauer beschreiben.

Es gibt da kein existentielles Problem. Ich habe den Algorithmus
einfach so geändert, dass ich das "globale" Dictionary nicht
modifiziere. Das Problem ist dadurch entstanden, dass ich
Änderungen an einer Coroutine vorgenommen habe, ohne zu erkennen,
dass ein Funktionsparameter geteilt wird. Sah ja lokal aus.

MfG
0 new messages