2016-05-04 17 views
2

私はexec()で実行する必要があるコードをいくつか持っていますが、どの行がZeroDivisionErrorを呼び始めているのか知りたいと思います。ここでexec()経由で実行されたZeroDivisionErrorの引数を取得するには?

例:

code = \ 
''' 
a = 9 
b = 0 
c = a/b 
print(c) 
''' 
>>>exec(code) 
--------------------------------------------------------------------------- 
ZeroDivisionError       Traceback (most recent call last) 
<ipython-input-3-00bada8e7a44> in <module>() 
     5 print(c) 
     6 ''' 
----> 7 exec(code) 

<string> in <module>() 

ZeroDivisionError: division by zero 

これは結構ですが、それは誤り、他のタイプのために発生したとして、私は例外の引数としてc = a/b代わりのexec(code)を持っているしたいと思います:

code = \ 
''' 
a = 9 
b = 0 
c === b 
print(c) 
''' 
>>>exec(code) 
    File "<string>", line 4 
    c === b 
     ^
SyntaxError: invalid syntax 

この場合、SyntaxErrorはエラーの原因となった行を直接指しています。

なぜこの違いがありますか? ZeroDivisionErrorを正しく指示するにはどうすればよいですか?

UPDATEは

私はSchoreによって提案された「compile()ソリューション」を試してみましたが、私の場合は期待どおりに動作しませんでした:

code = \ 
''' 
a = 9 
b = 0 
c = a/b 
print(c) 
''' 
z = compile(code, "", "exec") 
>>>exec(z) 
ZeroDivisionError       Traceback (most recent call last) 
<ipython-input-8-857f94e79b67> in <module>() 
     6 ''' 
     7 z = compile(code, "", "exec") 
----> 8 exec(z) 

? in <module>() 

ZeroDivisionError: division by zero 
+0

私は、 'exec'(と' eval')が[セキュリティ上のリスク](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html)になりうること、 –

+0

はい、私はコードについてセキュリティチェックをしていますが、これまでは書かれたコードスニペットのためだけで、うまくいくはずです。 –

答えて

2

理由は、ゼロ除算エラー===は実行時エラーであり、===はコンパイラの種類のエラーです(これは、Pythonでは===がコンピュータ命令に変換されたときに見つかりますが、コンパイラは実際にはありません)。

エラーの適切な行を得るためにできることは、コードを別々の行に分割し、ループごとに1つずつ実行し、例外を引き起こす行を出力することです。

+1

私はそのような解決策について考えました。私はコードを行に分割する必要はないので、より良い方法が可能かどうかをチェックしたいと思っていましたが、この非常に特殊なケースです。もちろん、他の選択肢がない場合は、私はそうするでしょう。 –

+1

FWIW、標準のCPythonインタプリタはPythonのソースコードをCPUのマシンコードにコンパイルしませんが、実際にはPythonマシンのマシンコードであるPythonのバイトコードにコンパイルします。また、 'exec'に渡すコードを明示的にコンパイルするために使用できる' compile'関数があります。興味深い情報については、http://stackoverflow.com/questions/2220699/whats-the-difference-between-eval-exec-and-compile-in-pythonを参照してください。 –

1

あなたは、コンパイルを使用することができます。

>>> code = \ 
... ''' 
... a = 9 
... b = 0 
... c = a/b 
... print(c) 
... ''' 
>>> c = compile(code, "", "exec") 
>>> exec(c) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "", line 4, in <module> 

ZeroDivisionError: integer division or modulo by zero 

あなたのコードを分割せずに行番号を取得するこの方法。

+0

私はエラーメッセージの行番号を取得しません... –

+0

この動作は、あなたのPython環境に固有のことがあります。彼のアプローチはどこでもうまくいくので、Michel Keijzersの答えをお試しください。あなたのコードを分割し、行ごとに実行することは、醜いものではありません... – Schore

+0

明日まで待つつもりです。私はZeroDivisionErrorクラスのリファクタリングについて考えていましたが、この種のケースを処理するための特定のクラスを作成しました。しかし、私は今それをするつもりはありません... –

関連する問題