2012-04-09 2 views
4

사용자가 numpy 및 scipy의 함수를 포함하는 자체 작성 수학 함수를 사용할 수 있어야하는 프로그램을 작성 중입니다. scipy.special.wofz().Python : sympy.sympify를 사용하여 수학 함수에서 안전한 eval() 수행

이러한 기능은 파일에 저장되고 프로그램에서 문자열로 가져옵니다. 나는 주위를 둘러 보았다. 그 eval() 또는 exec()는 그것을하는 안전한 방법이 아니다. 예. here.

좋은 사용자는 우수한 사용자 시스템에 액세스 할 수있는 악의적 인 사용자로부터 파일을로드합니다.

나는이 같은 일을 생각했다 :

#!/bin/python 
from scipy.special import * 
from numpy import * 
import sympy 

# Define variable a 
vars = {"a":1} 
# This is the string I get from a file 
string = "wofz(a)" 

parsed_string = sympy.sympify(string) 
parsed_string.evalf(subs=vars) 

그러나,이 작동하지 않습니다. 단지 다음을 반환합니다 :

wofz (a)는 평가되지 않습니다. 그런 식으로 일하기로되어 있습니까?

나는 또 다른 생각을 가지고 있었다 : 그래서이 수학 함수가 sympify를 통해 얻어지면 안전 할 것이라고 생각했다.

(0.36787944117144233+0.60715770584139372j) 

가 있음은 안전한가요 : 잘 돌아갑니다 작동

globals = {wofz:wofz} 
eval(str(parsed_string), vars, globals) 

: 나는 단지 같은 것을 할 수 있을까? 나는 그것이 좋지 않다는 것을 안다.

도와주세요.

답변

4

sympy를 사용하면 더 안전한 옵션입니다.

import sympy 
from sympy.core.function import Function 
from sympy.core import S 
from sympy import sympify 
from sympy.functions import im 
from scipy.special import wofz 

class Wofz(Function): 
    is_real = True 
    @classmethod 
    def _should_evalf(csl,arg): 
     return True 
    def as_base_exp(cls): 
     return cls,S.One 

    def _eval_evalf(cls, prec): 
     return sympy.numbers.Number(im(wofz(float(cls.args[0])))) 

print sympify("Wofz(2)",{'Wofz':Wofz}).evalf() 

출력 (당신이 어떻게 든 허수 부분 처리해야합니다) : 문자열이 유일하게 신뢰할 수없는 정보 인 경우

0.340026217066065 
+0

아아, 내가 가진 문제는'sympy.functions'에'wofz' 함수의 정의가 없다는 것입니다. – user1322192

+0

당신은'im' 대신're'를 사용하고 싶었지만, 맞습니까? is_real 플래그는 무엇을 하는가? 거기에 허수를 얻기 위해 'return Number (re (...)) + Number (im (...)) * 1j'와 같은 것을 할 수 있습니다. – user1322192

+1

@ user1322192 SymPy에 항상 기여할 수 있습니다. 결국 오픈 소스입니다. [개발 워크 플로] (https://github.com/sympy/sympy/wiki/Development-workflow)를 보면 알기 쉽게 설명되어 있습니다. – VPeric

0

을, 내가 생각하는 안전해야 다음으로

제한된 어휘로 eval()을 사용하고 허용되는 이름의 사전 인 두 번째 인수를 전달하십시오. 여기서는 __builtins__이 무해한 것으로 정의됩니다 (http://docs.python.org/library/functions.html#eval 참조).

>>> import numpy as np 
>>> d = dict(linspace=np.linspace, range=range, __builtins__=None) 
>>> eval("str(1), 2+2") 
('1', 4) 
>>> eval("str(1)", d) 
Traceback (most recent call last) 
NameError: name 'str' is not defined 

>>> eval("{'a': linspace(0, 0.5, 6)}, range(2)", d) 
({'a': array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5])}, [0, 1]) 
>>> eval("linspace.__dict__", d) 
Traceback (most recent call last) 
RuntimeError: function attributes not accessible in restricted mode 
관련 문제