eval
を使用することは悪い習慣であると一般に認められています。 this questionへの受け入れられた答えは、ほとんど常により良い選択肢があると述べています。しかし、標準ライブラリのtimeit
モジュールがそれを使用しています。私はより良い選択肢が見つからない場合に遭遇しました。eval Unittestの主張のバージョン*良いアイデアですか?
unittest
moduleは、それが失敗した場合は、必要に応じてmsg
を印刷し、何かを主張することができ、フォーム
self.assert*(..., msg=None)
のアサーション機能を持っています。これは
for i in range(1, 20):
self.assertEqual(foo(i), i, str(i) + ' failed')
のようなコードが今foo
は、例えば、一方では
def foo(i):
if i % 5 == 0:
raise ValueError()
return i
その後、
- を例外を発生させることができた場合を考え、
msg
は印刷されません実行することができますassertEqual
は技術的に反論の繰り返しと呼ばれることはありませんでした。 - 一方、基本的に
foo(i) == i
は真実ではありませんでした(確かにfoo(i)
は実行が完了していないため)msg
を印刷すると便利です。
エラーの原因が例外であっても、msg
を出力するバージョンを希望します。これにより、どの呼び出しが失敗したのかを正確に理解することができます。 eval
を使用して、私はそのような(ちょうどポイントを説明するために、やや単純化したバージョンである)、以下のような文字列を取ったバージョンを書き込むことによってこれを行うことができます:
def assertEqual(lhs, rhs, msg=None):
try:
lhs_val = eval(lhs)
rhs_val = eval(rhs)
if lhs_val != rhs_val:
raise ValueError()
except:
if msg is not None:
print msg
raise
、その後の
for i in range(1, 20):
self.assertEqual('foo(i)', 'i', str(i) + ' failed')
を使用してもちろん技術的には、assert*
への各コールをtry/except/finally
の中に置くことで完全に異なった方法で行うことも可能ですが、私は非常に冗長な選択肢しか考えられませんでした(msg
を複製する必要もあります)。
ここではeval
の正当な使用がありますか、それとも良い方法がありますか?
これを行うことでどのような問題を解決しようとしていますか? – snakecharmerb
@snakecharmerb質問に記載されているように、「This is running code like」の後にスニペットを実行し、失敗した反復で 'msg'を出力させます。 –
確かに、それは既存の行動を得るよりもどうですか?私はあなたが無料で得るstacktraceと例外メッセージを読んでいる以上の利点を見ません。 – snakecharmerb