2016-12-11 14 views
3

からトラップPythonの例外は、私は1線式センサからの温度を取り、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を押すだけで問題が表示されます。ところで、私は必死にそこにかなりの数の例外文を入れている:)

根本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) 

を見

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 

「AtrributeErrorが上がっているようですが、私はできますそれをキャッチします。センサのアドレスが間違っているので、センサには「温度」という属性はありませんので、存在しませんので、例外を発生させる必要があります。どのようにこのエラーが表示され、

+3

'' self.attrs'プロパティは、無限再帰のスパイラルを引き起こすように見えるよう、AttributeError'は到達しません引き上げます。しかし、私はループがどこにあるトレースバックの断片から分かりません。 –

+0

コマンドラインから3つのコメントを分割しています。Python 3.4.0(デフォルト、Apr 11、2014、13:05:11) [GCC 4.8。2] on Linux >>> fromewire import onewire >>> ow = Onewire( "%s:%d"%( "localhost"、4304)) >>> 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__メソッドを持っているため、いかなる試みにアクセスしたときに、これが呼び出されます(私はその行に達しれることは決してありません言うことができる限りライン81に上げAttributeErrorと混同しないでください。) Sensorインスタンスの属性がAttributeErrorで失敗します。 self.attrsのプロパティを読み取ろうとするとAttributeErrorが発生すると、Pythonはこれを名前がattrsの属性がないものとして解釈します。したがって、__getattr__を呼び出してattrs属性の値を検索します。しかし、もちろん、__getattr__にはself.attrsを読み込もうとしているので、スタックオーバーフローが発生するまで何度も何度も繰り返します。それをデバッグする

一つの方法は、次のようにonewire/__init__.pyattrsプロパティを交換することです。それはAttributeErrorをキャッチし、そのトレースバックを表示し、別の例外を発生させます。異なる例外は、Pythonが属性値を見つけるために__getattr__に行くのを止めます。あなたはsystracebackモジュールをインポートする必要があります:

@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への3つの呼び出しとtraceback.print_tbへの呼び出し(およびsystraceback輸入)なしで行うことができます:Pythonの3 exceptブロック内に例外がスローされたことを検出し、両方のトレースバックを出力します。

もう1つの方法はAttributeErrorOnewire.get()(行32-33のonewire/__init__.py)にキャッチして別の例外を発生させることです。

+0

ありがとうございました!、成功、例外を叩いた後も次のセンサーに続きました。私はむしろPythonには新しく、あなたが望むのでなければgithubのバグとしてこれを提出するつもりです。次のコメントが出力されます。 –

+0

加熱する@ HC1:〜/ OW $ ./one-wire-redis-write2.py INFO:ルート:検出されたデバイス28.BBE826060000(タイプ= DS18B20) INFO:ルート:検出されたデバイス28.438128060000(タイプ= DS18B20) はAttributeError (タイプ= DS18B20) INFO:root:デバイスまたは属性が見つかりませんでした%s INFO:root:foundデバイス28.CBBA28060000(タイプ= DS18B20) INFO:root:foundデバイス28.9DAF28060000(タイプ= DS18B20) INFO:root:見つかったデバイス28.8C8D27060000(type = DS18B20) INFO:root:found device 28.B67E27060000(type = DS18B20) heat @ hc1:〜/ ow $ –

+0

@FarmerGiles:これをGitHubのissue trackerに送信したいのであればプロジェクト、気軽に。そうした場合は、この質問に戻るリンクを含めてください。 –

関連する問題