Und auch die Aesthetik von
f.setMyProperty(g.getSomeProperty() * h.getOtherProperty())
vs
f.myProperty = g.someProperty * h.otherProperty
ist in meinen Augen klar zum Vorteil des letzteren,
Ich mußte jetzt erstmal kräftig ein paar Beiträge zurück blättern, um zu verstehen, daß (und warum) wir vermeintlich unterschiedliche Auffassungen haben. Eigentlich meinen wir (auch noisefloor) nämlich das Gleiche. Was aber in meiner ganz ursprünglichen Frage noch halbgar war, hatte ich schon lange erweitert, aber nicht weiter erwähnt.
Ich hatte ursprünglich nur get/set in der Art:
def getValue():
return __Value
def setValue( v ):
__Value = v
Das hatte ich zwischenzeitlich erweitert mit:
property Value( getValue, setValue )
Somit habe ich einen pseudo-direkten Zugriff auf die Attribute, kanalisiert aber über die get/set-Methoden, die nebenbei auch noch ggf. weitere Aktionen (oder wenigstens Prüfungen) durchführen.
Ja, auch ich finde die 2. Methode übersichtlicher. Ich hatte die Diskussion mit
Zitat
Getter / Setter sind 'böse'
nur insofern falsch verstanden, als daß ich es so aufgefaßt hatte, daß man immer lieber direkten Zugriff auf die Attribute zulassen soll und eben keine get/set-Methoden zwischenschalten soll (darf).
Zitat
idiomatisch Python programmieren lernen, oder eben dein Ding machen. Beides ist ok, wenn du dich mit letzterem bei mir bewirbst, wirst du abgelehnt
Idiomatisch nur um der Idio(ma)tie Willen? Nein. Es "vernünftig" machen, aber ohne krampfhaft auf Teufel komm raus mir alles vorschreiben zu lassen? Ja. Mich woanders bewerben? Ganz sicher nicht.
Zitat
ich moechte aber noch mal das Thread-Thema aufgreifen:
Gut, daß Du es machst, denn ich hätte demnächst zu diesem Punkt hier eh nachgehakt. Mein aktuelles Projekt ärgert mich und ich will nicht ausschließen, daß "Threading" vielleicht einer der Auslöser für die Probleme ist, die ich gerade damit habe. Mir fehlt aber im Moment auch noch die Idee, wie ich es anders hinbekommen könnte.
Zitat
eine Bibliothek, die mich mit unkontrollierten Threads beglueckt, sehe ich kritisch.
Naja, das würde ich nicht so sehen. Gerade auf dem relativ weit unten angesiedelten Niveau einer Interpreter-Sprache ist das "unkontrolliert" eigentlich in sehr enge Grenzen verwiesen. Ein Binary aus einem C-Kompilat, das seinerseits vielleicht auch noch weitere, fremde Binaries verwendet, ist für mich da schon sehr viel eher ein Grund für Skepsis.
Ich sehe eine Bibliothek aber eben gerne als "black box", bei der ich mich von "außen" nicht darum kümmern muß, wie sie arbeitet. Das bedeutet, daß ich, am Beispiel dieser simplen Sensoren, mich eben auch nicht darum kümmern will, wie ein i2c-Bus funktioniert und wann / wie ich Werte aus dem Sensor auslesen kann. Ich will die Bib einfach nur benutzen, um ein Objekt zu erschaffen, das mir Werte auf Abruf liefert. Soweit aus Sicht des Anwendungs-Programmierers...
Der Bibliotheks-Programmierer wiederum muß sich darum kümmern, mit den nur absolut notwendigen Parametern zumindest ein funktionierendes Objekt zu erschaffen. Dazu gibt's dann sinnvollerweise Default-Werte und alles darüber hinaus sind dann "Bonscher", die die Sache runder machen. Auch der Bib-Programmierer muß sich aber normalerweise nicht mehr um die Schicht darunter kümmern, sondern kann seinerseits auch wieder diese als "black box" betrachten. So muß die Bib z.B. nicht wissen, mit welchen Pegeln und welchen Timings der i2c-Bus arbeitet. Es gibt eine API, die regelt, mit welchem Befehl ich einen Modus setze, mit welchem ich einen Wert (oder Datenblock) auslese usw.
Zitat
Threads sind zum einen *hart*. Es sieht einfach aus, aber du bekommst zB eine beliebiege Reihenfolge von unzusammenhaengenden I2C-Aufrufen auf deinen Bus. Ob und welche Konsequenzen das hat, haengt jetzt von den intimen Details der smbus-Modul-Implementierung ab. Kennst du die?
Nein, kann und will ich auch gar nicht. Wenn der low-level-Treiber spackt, gibt's eine Fehlermeldung an den Programmierer des Treibers.
Zitat
Zeitpunkt der Ermittlung und Abfrage der Werte liegen auseinander. Wie lange haengt vom Zufall des Schedulings ab, und wird bei zunehmender Anzahl von Threads immer unvorhersehbarer.
Das ist jetzt aber sehr allgemein und hat eigentlich mit dem "Spielkram", den der RasPi und z.B. ein DS18B20 liefert, nichts mehr zu tun. Eine Hochgeschwindigkeits-Präzisions-Temperaturmessung, bei der ich Werte mit 3 Nachkommastellen im Millisekunden-Intervall bekomme (ja, sowas führen wir bei uns in der Firma durch), führe ich garantiert nicht mit einem RasPi durch. Da bin ich schon froh, wenn er eine sleep(1000) nach nur 1100 abgearbeitet hat.
Zitat
Ich moechte vielleicht Sensor A schnell, und Sensor B nur ab und zu auslesen. Geht nicht.
Klar geht das, aber noch nicht mit dem Source aus den Anfängen dieses Threads. Ich bin aber gerade dabei, die Sensoren als Klassen zu kapseln. Und da hindert mich ja niemand, 2 oder mehr Sensoren zu "erschaffen". Ob die Architektur des Bus-Systems oder die des low-level-Treibers das noch mitmachen, mag dann auf einem anderen Blatt stehen...
Zitat
- Der PI ist resourcen-beschraenkt. Mehrere Threads bedeuten ggf. langsamere Ausfuehrung deines Haupt-Threads, weil das Scheduling und Task-Switching halt nicht umsonst ist.
- Ereignisbasierte Programmierung durch zB callbacks wird schwieriger - die laufen wenn man nicht aufpasst in verschiedenen Threads, und treten sich auf die Fuesse.
Insgesamt finde ich dafuer eine gute Loesung zu finden wesentlich relevanter als die Frage, ob und wo man nun getter/setter nutzt oder wie privat etwas sein soll.
Ich finde einen Hintergrund-Thread, der Meßwerte akzeptabel aktuell und mit Timestamp bereit stellt, quasi ähnlich einem Cache, im Moment noch die einzig sinnvolle Lösung. Wenn das "main" Programm die Parameter allerdings in irrsinnige Bereiche schiebt und z.B. den Sensor jede Millisekunde aktiviert, dann wird's blöd. Aber das kann die Bib ja in gewissen Grenzen durch die Setter eindämmen. Wenn der DHT22 z.B. nur alle 2 Sekunden einen Wert liefert, dann kann setInterval(v) prima dafür sorgen, daß das Polling nicht häufiger angeschubst wird.
Ich hatte mich seinerzeit aber selbst ins Bockshorn gejagt: Ich schrieb sowas in der Art wie "threading oder mittels after()". Und dabei hatte ich vergessen, daß after() ja wohl nur in der GUI zur Verfügung steht, während man in der CLI darauf verzichten muß. Oder gibt's da eine Alternative?
Und auf Ereignisse + Callback würde ich auch gerne verzichten. Die sind mir (zumindest in den anderen Sprachen, die ich bislang verwende) immer sehr suspekt und machen leider auch viel Probleme.
Wie gesagt: Bislang (habe noch nichts Gegenteiliges feststellen können) ist mir ein Hintergrund-Thread noch am ehesten sympathisch. Die aktivierende Methode wird sauber durchlaufen und beendet (keine "while AppRunning:" Endlos-Schleife). Einzig die etwas aus der Hand gegebene Kontrolle beim threading ist mir nicht immer ganz geheuer. Führt dies doch auch mal dazu, daß das "main" mit einem Fehler abbricht und der Thread glatt weiter läuft. Irgendwie auch blöd... Aber bisherige Versuche mit bis zu 6 Sensoren brachten den RasPi nun wirklich noch nicht an seine Leistungsgrenzen. Ich sehe eher die Echtzeit-Sprektum-Analyse eines internet-Radio-Streams als Problem, aber weiß Gott nicht die Sensor-Abfragen im 10-Sekunden-Takt.
Gruß, Michael