2016-12-11 1 views
3

저는 원 와이어 센서에서 온도를 가져 와서 온도를 재 지정하기 위해 스크립트 작업을하고 있습니다. 이 스크립트는 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 문이 누락 된 센서에 도달하면 스크립트가 무기한 중지되고 Ctrl 키를 치면 문제를 볼 수 있습니다. BTW 내가

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 제기 것 같다하지만 난 할 수 그것을 잡아라. 센서 주소가 잘못되어 센서에 "온도"속성이 없으므로 존재하지 않으므로 예외를 발생시켜야합니다.이 오류를 어떻게 볼 수 있으며 예외 또는 유사한 구조로 사용할 수 있습니까?

+3

'raise AttributeError'는 결코 도달하지 않습니다.'self.attrs' 속성이 무한 재귀 나선을 일으키는 것으로 보입니다. 그러나 루프가있는 추적의 조각에서 나는 이해할 수 없습니다. –

+0

다음은 명령 행에서 3 개의 주석으로 분리 된 것입니다. Python 3.4.0 (default, Apr 11, 2014, 13:05:11) [GCC 4.8.2] 리눅스에서 >>>에서 온주 가져 오기 012 디렉토리를 클릭합니다. >>> s = ow.sensor ("28.02CA27060000") >>> 온도 = s.read ("온도") >>> s = ow.sensor ("28.12CA27060000") >>> 온도 = s.read ("온도") –

+0

^가장 최근의 CTraceback 마지막으로 전화) : 파일 "", 줄 1, 파일 "/usr/local/lib/python3.4/dist-packages/onewire/__init__.py"85 번째 줄에 읽음 return self .__ getattr__ (attr) 파일 "/usr/local/lib/python3.4/dist-packages/onewire/__init__.py", 80 행, __getattr__ attr이 self.attrs에없는 경우 : –

답변

1

가장 좋은 추측은 attrs 속성의 무엇인가가 AttributeError을 일으키는 것입니다.

를 클래스 Sensor__getattr__ 방법이 있기 때문에, 시도는에 액세스 할 때마다이가 호출됩니다 (I 그 라인에 도달하지 도착 결코 말할 수까지 라인 (81)에 제기 된 AttributeError와 혼동하지 마십시오.) Sensor 인스턴스의 특성이 AttributeError으로 실패합니다. self.attrs 속성을 읽으려는 시도가 AttributeError 일 때, 파이썬은 이것을 attrs이라는 속성이없는 것으로 해석합니다. 그래서 속성의 값을 찾으려면 __getattr__이 필요합니다. 그러나 물론 __getattr__에는 self.attrs을 읽으 려하므로 스택 오버플로가 발생할 때까지 모든 것이 반복됩니다.

디버그 방법 중 하나는 onewire/__init__.pyattrs 속성을 다음과 같이 바꾸는 것입니다. AttributeError을 잡아서 추적을 표시하고 다른 예외를 발생시킵니다. 다른 예외는 파이썬이 __getattr__으로 가서 속성 값을 찾지 못하도록합니다. print에 세 가지 통화 및 traceback.print_tb 호출 (과 systraceback 수입)없이 당신이 실제로 할 수 파이썬 3에서

@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)) 

: 당신은 systraceback 모듈을 수입해야 파이썬 (3) except 블록 내에서 예외가 발생하고 두 역 추적을 모두 인쇄합니다.

또 다른 방법은 AttributeErrorOnewire.get() (줄 32-33, onewire/__init__.py)에 붙잡고 다른 예외를 발생시키는 것입니다.

+0

감사의 말 : 성공, 그것은 예외를 쫓은 후 다음 센서로 계속 진행된다. 나는 파이썬에 대해 오히려 새로운데, 당신이 원하지 않는 한 github에 버그로 제출할 것입니다. 다음은 현재 출력물입니다. –

+0

난방 @ hc1 : ~/ow $ ./one-wire-redis-write2.py 정보 : 루트 : 발견 된 장치 28.BBE826060000 (유형 = DS18B20) 정보 : 루트 : 발견 된 장치 28.438128060000 (유형 = DS18B20) AttributeError 정보 : 루트 : 장치 또는 특성을 찾을 수 없습니다. % s 정보 : 루트 : 발견 된 장치 28.CBBA28060000 (유형 = DS18B20) 정보 : 루트 : 발견 된 장치 28.9DAF28060000 (유형 = DS18B20) 정보 : 루트 : 발견 된 장치 28.8C8D27060000 (type = DS18B20) 정보 : 루트 : found device 28.B67E27060000 (type = DS18B20) heat @ hc1 : ~/ow $ –

+0

@FarmerGiles : 이것을 GitHub 문제 추적기에 제출하려면 프로젝트, 자유롭게. 그럴 경우이 질문에 대한 링크를 포함 시키십시오. –

관련 문제