Wrapping a pyvisa device in a class

1.5k views Asked by At

I'm working on a PyVISA program that talks to a power analyzer, and two other devices. I can successfully query the analyzer using:

import pyvisa
my_instrument = pyvisa.ResourceManager().open_resource('USB0::0x0B21::0x0025::39314C383030313939::INSTR')
print(my_instrument.query(':NUMeric:VAL?'))

I want to wrap this like so:

import pyvisa
class YOKO( pyvisa.resources.usb.USBInstrument ):

    def __init__(self):
        pyvisa.ResourceManager().open_resource('USB0::0x0B21::0x0025::39314C383030313939::INSTR')

I instantiate the class in a separate file, and call the same query - but to no avail. I've gone through a few syntax variations, but I keep getting errors:

AttributeError: 'YOKO' object has no attribute 'visalib'

Anyone know what I'm doing wrong? How do you wrap a PyVISA device?

1

There are 1 answers

0
Ordak On

1) You should call USBInstrument's __init__ on the first line of YOKO's __init__. Doing so should take care of setting visalib to its expected value. (cf: Why aren't Python's superclass __init__ methods automatically invoked?)

2) I wouldn't recommend subclassing pyvisa instruments. Rather, I'd instantiate a pyvisa instrument object as an attribute of your own base instrument class (i.e. use encapsulation instead of inheritance). As you build up your own collection of instrument classes, three things will happen:

A) You'll find that you want to slightly alter the behavior of pyvisa's methods; for instance, you may want to configure your own per-protocol minimum timeouts. You could achieve this by simply overriding methods, but then you might break calling code that relies on the non-altered behavior of pyvisa instruments.

B) You'll come up with your own method/attribute names that accidentally step on pyvisa instrument methods; pyvisa has lots of these, and they have nice, intuitive names that invite collisions.

C) You'll want varying amounts of lighter-weight behavior of your instruments as you get into things like sets of co-operating instruments or real-time data streaming. Basically, you'll end up with semantics & business logic that goes beyond mere instrument I/O, and it'll be natural to put that logic into per-instrument objects. If you keep the actual pyvisa instrument object as just an attribute (that can be kept completely uninitialized, if desired) of your own instrument class, you'll have a lot more freedom to add these semantics & logic in.

Item 2 is deeply subjective, but it is based on my experience going down this exact same road a couple of times in the past :D