Page 1 of 1

Dynamically Creating Channel Class Instance

Posted: Wed Jan 16, 2019 2:19 am
by Nadav
Per the API docs, channels returned by Manager OnAttach handlers are read-only objects, and the developer should create new instances of the correct type.
My question is, is there a way to dynamically create the correct type?

Cannot use ch.__class__ as it is always an instance of class Phidget.
Is it possible to use ch.getChannelClassName() to somehow create the proper class instance?

Otherwise we get code like this:

Code: Select all

    def on_manager_attach_handler(self, ch):
        if ch.getChannelClass() == ChannelClass.PHIDCHCLASS_DIGITALINPUT:
            ch_new = DigitalInput()
        elif ch.getChannelClass() == ChannelClass.PHIDCHCLASS_DIGITALOUTPUT:
            ch_new = DigitalOutput()
        ...

Re: Dynamically Creating Channel Class Instance

Posted: Wed Jan 16, 2019 11:57 am
by jdecoux
The code you have shown is the intended way to go about creating new objects at this time.

This is a hold-over from how other (statically typed) languages have to approach creating new Phidgets, which need to specify a type before the code is run. It's admittedly not optimized for how Python could handle it, but that's what exists for the time being.

Re: Dynamically Creating Channel Class Instance

Posted: Wed Jan 16, 2019 12:52 pm
by Patrick
Hi,

You can call ChannelClassName to get the name of the channel class. This will return something like 'PhidgetAccelerometer'. To get the corresponding Python class name, clip 'Phidget' off the ChannelClassName to get for ex. 'Accelerometer'. You can then use getattr to create an instance of the class as outlined for example here: https://stackoverflow.com/questions/482 ... y-imported. I haven't tried this, but don't see why it couldn't work.

-Patrick

Re: Dynamically Creating Channel Class Instance

Posted: Sat Feb 23, 2019 4:33 pm
by Nadav
Thanks for the suggestion.
Here is working code (without error-handling):

Code: Select all

klass = ch_readonly.getChannelClassName()
python_klass_name = klass.split('Phidget')[1]
ch_new = getattr(importlib.import_module('Phidget22.Devices.' + python_klass_name), python_klass_name)()    
# Set handlers, and remember to call open()