我正在编写一个脚本,用于从单线传感器获取温度并将温度设置为redis。该脚本从名为alias1.py的文件中获取单线设备列表,该文件包含友好名称对和单线总线传感器地址对,并依次获取每个设备的温度。但是,如果传感器不可用,我想捕获异常并跳过它。目前这只是将它设置为6度,但我可能会稍后更改动作。不幸的是,我遇到了这个困难,在其他情况下看不到直接并行。
#!/usr/bin/python3
import logging
from onewire import Onewire
import redis
from alias1 import sensors
logging.basicConfig(level=logging.DEBUG)
room_float = {}
room_integer = {}
rooms ={}
ow = Onewire("%s:%d" % ("localhost", 4304))
for key in sensors:
roomID = sensors[key]
s = ow.sensor(roomID)
try:
temperature = s.read("temperature")
logging.info("found device %s (type = %s)" % (s.path,s.sensor_type))
except (RuntimeError, TypeError, NameError, AttributeError):
temperature = bytes([54])
logging.info("device or attribute not found %s")
rooms[key] = temperature
float_temp = float(temperature)
int_temp = int(float_temp)
r_server = redis.Redis('localhost')
r_server.hset(key, "temp_now", int_temp)
一旦for语句到达丢失的传感器,脚本将无限期挂起,只有通过点击控件c才能看到问题。顺便说一下,我在绝望中提出了不少异常陈述:)
File "./one-wire-redis-write2.py", line 17, in <module>
temperature = s.read("temperature")
File "/usr/local/lib/python3.4/dist-packages/onewire/__init__.py", line 85, in read
return self.__getattr__(attr)
File "/usr/local/lib/python3.4/dist-packages/onewire/__init__.py", line 80, in __getattr__
if attr not in self.attrs:
< Above line 80 repeated ad nauseum >
if attr not in self.attrs:
File "/usr/local/lib/python3.4/dist-packages/onewire/__init__.py", line 107, in attrs
self._attrs = self._ow.get(self.path).split(',')
File "/usr/local/lib/python3.4/dist-packages/onewire/__init__.py", line 33, in get
return _ow.get(str(os.path.join(self._path, *path)))
KeyboardInterrupt
查看基础onewire模块的第80行https://github.com/kipe/python-onewire/blob/master/onewire/init.py
def __getattr__(self, attr):
if attr not in self.attrs:
raise AttributeError('Attribute "%s" not found in %s.' % (attr, self.__str__()))
return self._ow.get(self.path, attr)
似乎引发了AtrributeError但我无法捕获它。传感器没有属性&#34;温度&#34;因为传感器地址是错误的所以不存在所以应该提出异常任何想法我怎么能看到这个错误并在一个除外或类似的结构中使用它?
答案 0 :(得分:1)
我最好的猜测是attrs
属性中的某些内容导致AttributeError
被引发。 (请不要将此与第81行提出的AttributeError
混淆:据我所知,该行永远不会到达。)
由于类Sensor
具有__getattr__
方法,因此每当尝试访问Sensor
实例的属性失败且AttributeError
时,都会调用此方法。当尝试读取属性self.attrs
引发AttributeError
时,Python将其解释为没有名称为attrs
的属性。因此,它会调用__getattr__
来查找attrs
属性的值。但是,当然,__getattr__
包含尝试读取self.attrs
,所以整个事情一次又一次地发生,直到堆栈溢出。
调试它的一种方法是使用以下内容替换attrs
中的onewire/__init__.py
属性。它捕获AttributeError
,显示其回溯并引发另一个异常。不同的异常阻止Python转到__getattr__
来查找属性值。您需要导入sys
和traceback
模块:
@property
def attrs(self):
try:
if self._attrs:
return self._attrs
self._attrs = self._ow.get(self.path).split(',')
return self._attrs
except AttributeError as e:
print("AttributeError in attrs property:")
traceback.print_tb(sys.exc_info()[2])
print("AttributeError: %s" % str(e))
print("=" * 80)
raise ValueError("AttributeError in attrs property: %s" % str(e))
在Python 3中,您实际上可以在没有调用print
和调用traceback.print_tb
(以及sys
和traceback
导入)的情况下完成操作:Python 3检测到except
块内正在抛出异常并将打印两个回溯。
另一种方法是在AttributeError
(Onewire.get()
的第32-33行)中捕获onewire/__init__.py
并引发其他异常。