2

このコードを使用して、文字列から数式を評価しています。そしてそれは機能します:

#!/usr/bin/env python
from __future__ import division
from math import *

expression = raw_input()

# Math functions
safe_list = ['math', 'factorial', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'hypot', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh'] 

# Create safe directory
safe_dict = dict([(key, locals().get(key, None)) for key in safe_list]) 
safe_dict['abs'] = abs

result = eval(expression, {"__builtins__": None}, safe_dict)
print result

私はそれを次のような関数でラップしました:

#!/usr/bin/env python
from __future__ import division
from math import *

def calculate(expression):
    # Math functions
    safe_list = ['math', 'factorial', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'hypot', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh'] 

    # Create safe directory
    safe_dict = dict([(key, locals().get(key, None)) for key in safe_list]) 
    safe_dict['abs'] = abs

    result = eval(expression, {"__builtins__": None}, safe_dict)
    if isinstance(result, float) and result.is_integer():
        result = int(result)
    print result

expr = raw_input()
calculate(expr)

また、基本的な操作では引き続き機能しますが、で定義されている機能はいずれも機能していませんsafe_dict5**5両方のプログラムで動作しsin(pi)ますが、コードの最初のサンプルでは動作し、2番目のサンプルでは動作しません。トレースバックは

Traceback (most recent call last):
  File "stack.py", line 20, in <module>
    calculate(expression)
  File "stack.py", line 14, in calculate
    result = eval(expression, {"__builtins__": None}, safe_dict)
  File "<string>", line 1, in <module>
TypeError: 'NoneType' object is not callable
4

3 に答える 3

7

失敗する理由は、数学モジュールからインポートする関数が関数内のローカル変数ではないためです。それらはグローバルです。したがって、locals()を読み取ってdictに挿入すると、すべての1つにNoneが挿入されます。get(key, None)を削除して直接アクセスした場合に表示されますlocals()[key]

より良い方法は、数学モジュールでgetattrを使用することです。import math実行(しない)from math import *してから実行しますsafe_dict = dict((k, getattr(math, k)) for k in safe_list)

于 2012-07-10T18:29:37.637 に答える
3

calculate()関数内に、locals()からインポートされた関数は含まれませんmath。したがって、 safe_dict多くのが入力されNoneます。

safe_dictの外側を構築することもできcalculate()ます。これには、に複数の呼び出しを行う場合にパフォーマンスが向上するという利点もありますcalculate()

于 2012-07-10T18:29:00.983 に答える
1

これは、にがあり、がモジュールであることが原因である可能性があり'math'ます。私には、それがしているように見えます、それはそれがしているようにそれを窒息させるでしょう。safe_listmathevalmath()

から削除'math'してみてsafe_list、それがまったく役立つかどうかを確認してください。

ちなみに、これが本当にあなたがやりたいことをするための最良の方法であるかどうかはわかりません。デザインの変更が必要だと思います。

于 2012-07-10T18:25:45.487 に答える