Problem importing class from another Python file

172 views Asked by At

I'm very new to Python, I'm having trouble wrapping my head around some aspects of using Python.

I'm writing code to control a couple of instruments using pyvisa. For simplicity, I'm only showing one instrument here (a Thor Labs power meter). If I put all my code together into one file I can get things to work. The code below first searches for available instruments, and defines the instrument ID (ThorID):

import pyvisa
rm = pyvisa.ResourceManager()  # Set up resource manager
resource_list = rm.list_resources()  # Create a list of available instruments

# Thor Labs power meters should contain this string
Thor_str = "0x1313::0x8079"
# Search for a Thor Labs meter in the resource list
Thor = [i for i, s in enumerate(resource_list) if Thor_str in s]

if len(Thor) == 0:
   print("No Thor Labs power meter detected")
   ThorID = ""
else:
   print("Thor Labs power meter detected")
   ThorID = resource_list[Thor[0]]  # This is the Thor Labs VISA ID

Then I define the class powermeter

class powermeter:
"Power meter class. Contains parameter values and commands."

def __init__(self, wavelength=450, meter_range=200e-3, id=ThorID):
    """ Define default parameter values """
    self.wavelength = wavelength  # nm
    self.meter_range = meter_range  # W
    self.ID = id  # Meter's VISA ID
    self.name = ""  # Meter instance name

def connect(self):
    """Open a connection to the power meter"""
    self.name = rm.open_resource(self.ID)

def set_wavelength(self, wavelength):
    """Set the power meter wavelength (nm)"""
    self.name.write("CORR:WAV " + str(wavelength))

def set_range(self, meter_range):
    """Set the power meter range (W)"""
    self.name.write("POW:DC:RANG " + str(meter_range))

def read(self):
    """Read the power meter output (mW)"""
    return float(self.name.query("READ?"))*1000

Final 3 lines opens a connection to the meter and sets the wavelength (to 400 nm). I can confirm all this code together in one .py file works.

enter pm = powermeter()  # Create instance of powermeter
pm.connect()  # Connect to this power meter
pm.set_wavelength(400)  # Set wavelength to 400 nm

I run into lots of trouble trying to split the Class off into a separate .py file. I want to do this to try to keep my code tidier...eventually I'll add in a GUI and another class and I don't want one huge cumbersome monolith of text.

My naive first attempt has this as my main code, with the class as written above saved in PM_class.py:

import pyvisa

rm = pyvisa.ResourceManager()  # Set up resource manager
resource_list = rm.list_resources()  # Create a list of available instruments

# Thor Labs power meters should contain this string
Thor_str = "0x1313::0x8079"
# Search for a Thor Labs meter in the resource list
Thor = [i for i, s in enumerate(resource_list) if Thor_str in s]

if len(Thor) == 0:
    print("No Thor Labs power meter detected")
    ThorID = ""
else:
    print("Thor Labs power meter detected")
    ThorID = resource_list[Thor[0]]  # This is the Thor Labs VISA ID

from PM_class.py import powermeter

But I get an error in PM_class.py - NameError: name 'ThorID' is not defined

I don't understand that, because ThorID is clearly defined in the line before I try to import the Class?

Any advice on how to approach this would be very welcome!

1

There are 1 answers

1
Pozdniakov Filipp On

class powermeter is in another module, in this string

def __init__(self, wavelength=450, meter_range=200e-3, id=ThorID):

you try to init it with var ThorID but the class itself is encapsulated and cannot read this var from your current module. Try to define ThorID variable in PM_class.py or use

def __init__(self, wavelength=450, meter_range=200e-3, id=None):

and pass id when initialising the class

pmeter=powermeter(id=ThorID)