有没有办法让几个连续的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
如果所有这些都已关闭,但是按照目前的书写,它只取决于加热器温度计。有没有办法堆叠这些?
答案 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进行迭代。