Seite 1 von 1

Parameter in dynamischen Funktionsaufruf übergeben

Verfasst: Dienstag 17. Juni 2014, 13:18
von Damaskus
Hallo Zusammen,

ich suche nach einer Möglichkeit bei einem Callback eines Tinkerforge Bricks die UID des Bricks zu übergeben.
Da die Bricks über ein Interface konfiguriert werden können, vorallem die für den Brick zu verwendende Brick UID muss ich den Callback aufruf dynamisch machen.
Den Aufruf etc. bekomme ich auch Problemlos hin, allerdings fällt mir im Moment nicht die richtige Lösung ein um innerhalb der Klasse von __getattr__ die richtige "brickuid" nach cb_moisture bei jedem Aufruf des Callbacks weiter zu reichen.

Anbei ein Bsp. was es evtl. besser beschreibt:

Code: Alles auswählen

# !/usr/bin/env python
# -*- coding: utf-8 -*-  

HOST = "192.168.178.36"
PORT = 4223
UID = ["kwJ", "kyc", "hjk", 'Fgt']

from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_moisture import Moisture
import string


class MyClass(object):
    def __init__(self):
        pass

    def cb_moisture(moisture):
        # brickuid = ??? <<< Hier wird die BrickUID benoetigt
        print('Moisture Value: ' + str(moisture))

    def __getattr__(self, name):
        if name.startswith('cb_moisture_'):
            brickuid = name[12:]  # <<< hier ist die BrickUID
            return self.cb_moisture

cb = MyClass()

if __name__ == "__main__":
    ipcon = IPConnection()
    ipcon.connect(HOST, PORT)

    for u in UID:
        m = Moisture(u, ipcon)
        m.set_moisture_callback_period(1000)
        methodToCall = getattr(cb, 'cb_moisture_' + string.lower(u))
        m.register_callback(m.CALLBACK_MOISTURE, methodToCall)

    raw_input('Press key to exit\n')
    ipcon.disconnect()

Re: Parameter in dynamischen Funktionsaufruf übergeben

Verfasst: Dienstag 17. Juni 2014, 13:29
von EyDu
Hallo.

Das kannst du einfach mit ``functools-partial`` machen.

Re: Parameter in dynamischen Funktionsaufruf übergeben

Verfasst: Dienstag 17. Juni 2014, 14:20
von BlackJack
@Damaskus: Das mit `__getattr__` sieht extrem kompliziert aus. Du missbrauchst nicht wirklich vorhandene Methodennamen um Argumente zu übergeben wobei die auch gar nicht tatsächlich in den Quelltext geschrieben werden, sondern generiert werden. Warum‽

Re: Parameter in dynamischen Funktionsaufruf übergeben

Verfasst: Dienstag 17. Juni 2014, 14:39
von Damaskus
@BlackJack: Das Bsp. war ziemlich reduziert. Es geht mir darum die Messwerte von ca. 40 Bricklets in einer DB zu speichern und über die jeweilige Id einem Sensor zu zu weisen. Und da die Konfiguration der Sensoren sich immer wieder ändert dachte ich, ich übergebe die ID im Funktionsname des Callbacks, werte den Aufruf aus, schneide die UID aus und mappe den Aufruf an eine "Universal" Funktions. Und muss nicht x-mal den Callback schreiben...

Code: Alles auswählen

def cb_moisture_xyz(moisture):
    uid = 'XYZ'
    print('Moisture Value: ' + str(moisture) + '     UID: ' + uid)

Wenn ich aber von Anfang an, an "functools" gedacht hätte, wäre so ein Krampf mit __getattr__ nie heraus gekommen.
Lösung mit functools:

Code: Alles auswählen

# !/usr/bin/env python
# -*- coding: utf-8 -*-  

HOST = "192.168.178.36"
PORT = 4223
UID = ["kwJ", "kyc"]

from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_moisture import Moisture
import string
import functools


def temp_cb_moisture(moisture, uid):
    print('Moisture Value: ' + str(moisture) + '     UID: ' + uid)

if __name__ == "__main__":
    ipcon = IPConnection()
    ipcon.connect(HOST, PORT)

    for u in UID:
        m = Moisture(u, ipcon)
        m.set_moisture_callback_period(1000)
        cb_moisture = functools.partial(temp_cb_moisture, uid=u)
        m.register_callback(m.CALLBACK_MOISTURE, cb_moisture)

    raw_input('Press key to exit\n')
    ipcon.disconnect()
@EyDu: Danke!