Программирование с подключенным оборудованием

Думаю, проще всего это будет показать на примере, но вопрос общий. Скажем, я использую такую ​​библиотеку, как PyVISA, которая связывает устройства GPIB с моей программой. Я настроил класс Python для каждого инструмента, поэтому для источника питания у меня может быть что-то вроде этого:

import visa

class PowerSupply:
    def __init__(self):
        rm = visa.ResourceManager()
        self.ps = rm.open_resource('GPIB0::12::INSTR')
    def getVoltage(self):
        return self.ps.ask('VOLT?')
    def setVoltage(self,v):
        self.ps.write('VOLT '+str(v))
    ...

ps = PowerSupply()
ps.setVoltage(10)

К сожалению, есть шанс, что функция rm.open_resource может не работать или может вернуть None, если устройство по этому адресу не существует (в моем коде я фактически написал функцию, которая вместо этого делала это). Мой вопрос: как лучше всего кодировать такой класс, как PowerSupply? Можно написать исключения в каждый метод, проверяющий, существует ли self.ps или нет None, но, похоже, должен быть способ получше. Есть?!


person roboguy222    schedule 08.10.2014    source источник
comment
Конечно, в этом случае __init__ должен выйти из строя, выдавая ошибку?   -  person jonrsharpe    schedule 08.10.2014
comment
к дальнейшему комментарию Джона ... работа вызывающего абонента должна заключаться в управлении зависимостью try:ps=PowerSupply(); except: do_something_else() ... и init обязательно должен вызвать ошибку о том, что источник питания не найден   -  person Joran Beasley    schedule 08.10.2014
comment
@jonrsharpe: В вопросе говорится, что open_resource может вернуть None. Так что нет, __init__ в этом случае не подведёт. Но исправление состоит в том, чтобы сделать сбой в этом случае. Добавьте if not self.ps: raise SomeException('failed to open resource') или что-то подобное.   -  person abarnert    schedule 08.10.2014
comment
Вы можете еще больше отделить PowerSupply от своего ресурса, внедрив его в метод __init__() вместо того, чтобы создавать его там. Таким образом, вы можете переключать реализацию, пока интерфейс совместим.   -  person P3trus    schedule 13.01.2015


Ответы (1)


Можно написать исключения в каждый метод, который проверяет, существует ли self.ps/не является ли None, но, похоже, должен быть лучший способ. Есть?!

да. То, как вы написали свой код, если self.ps когда-либо будет None, с самого начала будет None и больше никогда не изменится. Итак, вместо того, чтобы тестировать его в каждом методе, просто протестируйте его один раз:

def __init__(self):
    rm = visa.ResourceManager()
    self.ps = rm.open_resource('GPIB0::12::INSTR')
    if self.ps is None:
        raise PowerSupplyException('Unable to open resource GPIB0::12::INSTR')

Теперь любой код, который конструирует PowerSupply, должен либо обрабатывать это исключение, либо быть готовым к его распространению, но ваш вопрос подразумевает, что open_resource все равно может вызвать исключение, так что это не может быть проблемой. Кроме того, кажется, что это правильное место для обработки — на верхнем уровне вашей программы, где бы вы ни создавали PowerSupply в ответ на какую-либо команду GUI, CLI или сети, именно здесь вы готовы справиться с невозможностью создать его, не так ли?

И любому коду, который использует уже построенный PowerSupply, не о чем беспокоиться. Вы знаете self.ps is not None, иначе вы не смогли бы вернуть объект из конструктора.

person abarnert    schedule 08.10.2014