Seite 1 von 1

Dynamisch Methoden einer Klasse referenzieren

Verfasst: Donnerstag 10. Mai 2012, 17:19
von pommespaula
Hallo,

schöne Grüße erst einmal an das Forum. Ich bin recht neu in der Python-Programmierung und habe in der nächsten Zeit sicherlich etliche Fragen. Vielen Dank also schon einmal vorweg für alle eure Antworten.

Ich versuche aktuell ein Messprogramm für unser Labor zu schreiben. Jedes Messgerät soll als Objekt angelegt werden. Die Methoden des Objekts repräsentieren dann Kanäle des Messgeräts.

Ich möchte mein Vorhaben stark vereinfacht anhand eines Voltmeters erklären. Das Voltmeter besitzt z.B zwei Kanäle um Spannungen zu messen. Je nach Experiment können dieses Spannungen aber eine andere Bedeutung haben, mal repräsentieren sie eine Temperatur oder ein anderes mal die Stärke eines Magnetfeldes. Der Benutzer soll nun in der Lange sein diesem Kanal einen physikalisch sinnvollen Namen zu geben und darüber zugreifen zu können.

Was ich nun wissen möchte ist, wie ich dieses am geschicktesten realisiere. Hier mal was ich mir gedacht habe und was auch funktioniert.

Code: Alles auswählen

class voltmeter(object):
        def __init__(self, name1, name2):
                self.__channels = {name1 : self.channel01,
                                   name2 : self.channel02}
       
        def readchannel(self, name):
                channelreference = self.__channels[name]
                return channelreference()
        
        def channel01(self):
                return "Spannungswert 01"
 
        def channel02(self):
                return "Spannungswert 02"

               
FooVolt = voltmeter('magnetfeld', 'temperatur')
print FooVolt.readchannel('magnetfeld')
print FooVolt.readchannel('temperatur')

Code: Alles auswählen

Ausgabe:
# Spannungswert 01
# Spannungswert 02
Da dieses einen sehr wichtiger Teil des Programms ausmacht, möchte ich gerne vorweg sicherstellen den richtigen Weg zu gehen. Allerdings bin ich mir nicht sicher ob dieses der richtige Weg ist um Methoden zu referenzieren.
Ich würde mich sehr freuen, wenn mir jemand sagen könnte ob ich die Sache richtig oder falsch angehe. Lasst mich aber auch bitte wissen, wenn ihr meine Frage nicht versteht.

Vielen Dank schon einmal für alle Antworten.

Re: Dynamisch Methoden einer Klasse referenzieren

Verfasst: Donnerstag 10. Mai 2012, 20:10
von BlackJack
@pommespaula: Das kann man so machen, aber ich würde die Methoden `channel01()` und `channel02()` mal in Frage stellen. Die beiden Kanäle werden ja nicht komplett unterschiedlich angesprochen werden, so das eine Methode bei der der Kanal als Argument übergeben wird, viel wahrscheinlicher ist. Wenn man anfängt Namen durch zu nummerieren stimmt in 99% der Fälle etwas am Entwurf nicht.

Zur Form: Schau mal in den PEP 8 -- Style Guide for Python Code. Das müsste also `Voltmeter`, `read_channel`, und `foo_volt` heissen. Ausserdem Einrücken um vier Leerzeichen pro Ebene.

Und der doppelte Unterstrich bei `__channels` sollte zu einem werden.

Re: Dynamisch Methoden einer Klasse referenzieren

Verfasst: Donnerstag 10. Mai 2012, 20:42
von pommespaula
Hey Danke für deine Rückmeldung und deinen Link für "guten" Code.

Das Beispiel war sehr vereinfacht dargestellt und in dem Falle sicherlich wenig ideal. Im Realfall besitzt aber jeder Messaufbau viele Messgeräte mit sehr unterschiedlichen Funktionen. Ein Voltmeter z.B. besitzt z.B. mehre identische Spannungseingänge aber auch Funktionen wie Messbereich, Rauschfilterung, Integrationszeit, etc. Ein anderes Messgerät überwacht die Temperatur des Experiments. Über all diese sehr unterschiedlichen Funktionen von verschiedenen Messgeräten soll das Channel-Konstrukt als Abstraktionsebene gelegt werden. Wodurch ein einheitlicher Zugriff erlaubt wird.

* Messgerät Treiber -> Greift auf die Hardware des Messgeräts zu.
* Channel Interface -> Verknüpft die Funktionen der Messgeräte mit den "Channels" und erlaubt einen einfachen Zugriff darauf.
* Messprogramm -> Kann Channels auslesen und steuern.

Re: Dynamisch Methoden einer Klasse referenzieren

Verfasst: Donnerstag 10. Mai 2012, 21:32
von BlackJack
@pommespaula: Das ändert alles nichts daran, dass eine Methode pro Kanal wobei die Kanäle durchnummeriert sind, ein schlechter Entwurf ist. Dafür braucht man nur *eine* Methode, welche die Kanalnummer als Argument übergeben bekommt. Dann ist die Kanalnummer ein Wert, den man im Programm verarbeiten kann, vom Benutzer eingeben lassen kann, in Dateien speichern kann, und so weiter.

Re: Dynamisch Methoden einer Klasse referenzieren

Verfasst: Donnerstag 10. Mai 2012, 22:28
von pommespaula
@BlackJack Mh ich versuche gerade zu verstehen was du mir mitteilen möchtest. Die Kanäle unterscheiden sich ja in ihrer Funktionsweise und in der Art und Weise wie sie ausgelesen bzw. gesetzt werden fundamental voneinander. Ich wüsste gerade nicht wie ich ohne entsprechende Referenzen mein Vorhaben umsetzen sollte.

Re: Dynamisch Methoden einer Klasse referenzieren

Verfasst: Donnerstag 10. Mai 2012, 23:16
von BlackJack
@pommespaula: An einem Gerät unterscheidet sich das bei den verschiedenen Kanälen so grundsätzlich? Ich habe Schwierigkeiten mir das vorzustellen. Wenn das so unterschiedlich ist, wie kann man es dann auf gleichartige Kanäle umsetzen? Wenn die nicht alle gleichartig verwendbar sind, macht es ja keinen Sinn sie zu haben. Das klingt jetzt irgendwie so als wenn konkrete Methoden auf namenlose Kanäle abstrahiert werden, um sie im nächsten Schritt dann wieder mit konkreten Namen zu versehen‽

Re: Dynamisch Methoden einer Klasse referenzieren

Verfasst: Freitag 11. Mai 2012, 01:37
von pommespaula
Gemeinsam haben alle Channels aller Messgeräte immer nur, dass sie entweder einen Wert lesen oder senden. Es muss also zwischen Lese- und Schreibchannels unterschieden werden und mehr muss der Benutzer nicht wissen. Wie jetzt die genaue Kommunikation mit den Messgeräten über das GPIB Bus System geschieht und welche unterschiedlichen Befehlsätze gesendet werden soll über das Channelkonzept ausgebledendet werden. Den Benutzer kümmert es nichteinmal, dass die Channels zu unterschiedlichen Messgeräten gehören. Das Channel Konzept ist daher noch etwas allgemeiner gefasst als es im Beispiel der Fall ist.

Ich denke aber nochmal genau drüber nach, ob es Sinn es irgendwie mehr Sinn macht die Channels mittels Abfragen zu realisieren anstatt sie zu als Methoden zu realisieren. Vielen Danke für deine ganzen Anregungen, werde es im Hinterkopf behalten.

Re: Dynamisch Methoden einer Klasse referenzieren

Verfasst: Freitag 11. Mai 2012, 03:31
von BlackJack
@pommespaula: Vielleicht macht es auch mehr Sinn die Kanäle als Klassen zu modellieren. Und die Geräte als Container-Objekte auf deren Elemente man über die Kanalnummer oder einen symbolischen Namen zugreifen kann. So dass der Code dann zum Beispiel so aussehen kann:

Code: Alles auswählen

    device = Device()
    
    device[0].send(42)
    value = device[1].receive()

    for channel in device:
        print channel.number, channel.name, channel.direction
    # Prints '0 command OUT' and '1 voltage IN'.

    device['command'].send(42)
    value = device['voltage'].receive()

Re: Dynamisch Methoden einer Klasse referenzieren

Verfasst: Montag 14. Mai 2012, 01:23
von pommespaula
Ich werde die nächsten Tage/Wochen mal anfange Treiber für zwei Geräte zu schreiben. Werde mir danach genau überlegen wie ich das Channel-Interface am besten darüber legen und ggf. nochmal auf deine Vorschläge zurück kommen. Vielen Dank schon einmal für deine vielen Anregungen.