2017-09-12 52 views
1

我有一个需要解析为SymPy表达式的字符串列表。问题是,如果其中一个引发SympifyError异常,则以下字符串将不会返回在异常之前返回的完全相同的字符串SymPy表达式。Sympify为相同的输入返回不同的表达式

例如,下列代码:

import traceback 

from sympy.core import sympify 
from sympy.core.evaluate import evaluate 
from sympy.core.sympify import SympifyError 

if __name__ == '__main__': 

    equations = ['Eq(sin(pi/6), x/10)', 'Eq(x, 3))', 'Eq(sin(pi/6), x/10)'] 

    for equation in equations: 

     try: 
      with evaluate(False): 
       expr = sympify(equation) 

      print(expr) 

     except SympifyError: 
      traceback.print_exc() 

输出:

Traceback (most recent call last): 
Eq(sin(pi/6), x/10) 
    File "C:\Users\vini_\Anaconda3\lib\site-packages\sympy\core\sympify.py", line 354, in sympify 
Eq(sin(pi/6**1), x/10**1) 
    expr = parse_expr(a, local_dict=locals, transformations=transformations, evaluate=evaluate) 
    File "C:\Users\vini_\Anaconda3\lib\site-packages\sympy\parsing\sympy_parser.py", line 889, in parse_expr 
    code = stringify_expr(s, local_dict, global_dict, transformations) 
    File "C:\Users\vini_\Anaconda3\lib\site-packages\sympy\parsing\sympy_parser.py", line 791, in stringify_expr 
    for toknum, tokval, _, _, _ in generate_tokens(input_code.readline): 
    File "C:\Users\vini_\Anaconda3\lib\site-packages\sympy\parsing\sympy_tokenize.py", line 384, in generate_tokens 
    raise TokenError("EOF in multi-line statement", (lnum, 0)) 
sympy.parsing.sympy_tokenize.TokenError: ('EOF in multi-line statement', (2, 0)) 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "C:/Users/vini_/PycharmProjects/bugfix_simpify/main.py", line 22, in <module> 
    expr = sympify(equation) 
    File "C:\Users\vini_\Anaconda3\lib\site-packages\sympy\core\sympify.py", line 356, in sympify 
    raise SympifyError('could not parse %r' % a, exc) 
sympy.core.sympify.SympifyError: Sympify of expression 'could not parse 'Eq(x, 3))'' failed, because of exception being raised: 
TokenError: ('EOF in multi-line statement', (2, 0)) 

注意,第一和第三串是相同的,但是它们的输出是不同的(有一个附加的**1第二。一个是故意不正确的(括号不平衡),我使用的是evaluate(False)这一行,因为我需要表达式尽可能地接近原始字符串

我做错了什么?有什么方法可以解决这个问题,以便对于相同的输入字符串,输出是相同的?

环境:Python 3.6.1; SymPy 1.1.1

在此先感谢。

回答

0

当我移动上下文管理evaluatetry外面你的问题消失 - except表达:

import traceback 

from sympy.core import sympify 
from sympy.core.evaluate import evaluate 
from sympy.core.sympify import SympifyError 

equations = ['Eq(sin(pi/6), x/10)', 'Eq(x, 3))', 'Eq(sin(pi/6), x/10)'] 

for equation in equations: 
    with evaluate(False): 
     try: 
      expr = sympify(equation) 
     except SympifyError: 
      traceback.print_exc() 
     else: 
      print(expr) 

虽然这是你可能应该无论如何做(始终把尽可能少的try子句中) ,你不应该遇到这个问题,这似乎是一个错误 - 可能与上下文管理器evaluate未正确关闭有关。 下面是一个更简单的脚本(通过降低你获得)产生类似的问题:

from sympy import sympify, evaluate 
from sympy.abc import x,y 

try: 
    with evaluate(False): 
     sympify(")") 
except: 
    pass 

(x+y).simplify() 

I reported this bug

相关问题