多个Try-Excepts后跟pyse中的Else

时间:2010-02-03 00:10:20

标签: python exception-handling

有没有办法让几个连续的Try-Except子句只有在所有这些子句成功的情况下触发一个Else?

举个例子:

 try:
    private.anodization_voltage_meter = Voltmeter(voltage_meter_address.value) #assign voltmeter location
except(visa.VisaIOError): #channel time out
    private.logger.warning('Volt Meter is not on or not on this channel')
try:
    private.anodization_current_meter = Voltmeter(current_meter_address.value) #assign voltmeter as current meter location
except(visa.VisaIOError): #channel time out
    private.logger.warning('Ammeter is not on or not on this channel')
try:
    private.sample_thermometer = Voltmeter(sample_thermometer_address.value)#assign voltmeter as thermomter location for sample.
except(visa.VisaIOError): #channel time out
    private.logger.warning('Sample Thermometer is not on or not on this channel')
try:
    private.heater_thermometer = Voltmeter(heater_thermometer_address.value)#assign voltmeter as thermomter location for heater.
except(visa.VisaIOError): #channel time out
    private.logger.warning('Heater Thermometer is not on or not on this channel')
else:
    private.logger.info('Meters initialized')

如您所见,您只想打印meters initialized如果所有这些都已关闭,但是按照目前的书写,它只取决于加热器温度计。有没有办法堆叠这些?

5 个答案:

答案 0 :(得分:6)

考虑将try/except结构分解为一个函数,如果调用有效则返回True,如果失败则返回False,然后使用例如all()看到他们都成功了:

def initfunc(structure, attrname, address, desc):
  try:
    var = Voltmeter(address.value)
    setattr(structure, attrname, var)
    return True
  except(visa.VisaIOError):
    structure.logger.warning('%s is not on or not on this channel' % (desc,))

if all([initfunc(*x) for x in [(private, 'anodization_voltage_meter', voltage_meter_address, 'Volt Meter'), ...]]):
  private.logger.info('Meters initialized')

答案 1 :(得分:6)

就个人而言,我只有一个旅行变量init_ok或者其他一些。

将其设置为True,并将所有except子句设置为False,然后在末尾进行测试?

答案 2 :(得分:6)

尝试这样的事情。保持在第一次例外后不停止的原始行为

success = True
for meter, address, message in (
        ('anodization_voltage_meter',voltage_meter_address,'Volt Meter is not on or not on this channel'),
        ('anodization_current_meter',current_meter_address,'Ammeter is not on or not on this channel'),
        ('sample_thermometer',sample_thermometer_address,'Sample Thermometer is not on or not on this channel'),
        ('heater_thermometer',heater_thermometer_address,'Heater Thermometer is not on or not on this channel')):
   try:
       setattr(private,meter, Voltmeter(address.value):
   except (visa.VisaIOError,):
       success = False
       private.logger.warning(message)

if success: # everything is ok
    private.logger.info('Meters initialized')

答案 3 :(得分:3)

你可以保留一个布尔值,在开头初始化为:everythingOK=True 然后在所有除外块中将其设置为False,并仅在最后一行记录为真。

答案 4 :(得分:2)

你有很多非常相似的对象,在这种情况下,统一对待它们并使用数据驱动的方法通常会更好。

所以,我从你的..._meter_address对象开始。对我来说,它们听起来像米的配置,所以我有一个看起来像这样的类:

class MeterConfiguration(object):
    def __init__(self, name, address):
        self.name = name
        self.address = address

    def english_name(self):
        """A readable form of the name for this meter."""
        return ' '.join(x.title() for x in self.name.split('_')) + ' Meter'

也许你有更多的配置(目前存储在变量中)也可以在这里进行。

然后,我会得到您的计划所处理的所有仪表的摘要。我正在创建这些静态,但您可能正确地从配置文件中读取全部或部分此类信息。我不知道你的地址是什么样的,所以我做了些什么:)

ALL_METERS = [
    MeterConfiguration('anodization_voltage', 'PORT0001'),
    MeterConfiguration('anodization_current', 'PORT0002'),
    MeterConfiguration('sample_thermometer', 'PORT0003'),
    MeterConfiguration('heater_thermometer', 'PORT0004')
]

很酷,现在所有配置都集中在一个地方,我们可以用它来使事情更加统一和简单。

private.meters = {}
any_errors = False
for meter in ALL_METERS:
    try:
        private.meters[meter.name] = Voltmeter(meter.address)
    except VisaError:
        logging.error('%s not found at %s', meter.english_name(), meter.address)
        any_errors = True
if not any_errors:
    logging.info('All meters initialized.')

您可以使用例如private.meters['anodization_voltage']来引用特定的仪表,或者如果您需要对所有仪表执行某些操作,则可以使用仪表dict进行迭代。