我试图用eval
SymPy表达式来评估,它可以包含任何abc字母:
from sympy.abc import *
我想在方法中实现一种通过动态定义相关变量来处理NameError的方法。这是它的要点
try:
eval(expr)
except NameError as err:
msg = str(err)
pos = msg.find("'")
letter = msg[pos+1]
from sympy.abc import letter
很明显,sympy.abc中没有任何来信。这样会引发异常。另一个问题是,如果使用像theta这样的符号,那么只评估该符号的第一个字母。所以关于我如何能够首先设法导入字母值的任何提示,也许还可以处理像eta,phi等符号。
另一个重要问题是表达式中可能有许多不同的字母。我该怎么处理?
编辑:我已成功解决了这个问题。 以下是我的尝试:
def try_expr(expr):
try:
eval(expr)
except NameError as err:
msg = str(err)
pos = msg.find("'")
letter = msg[pos+1]
pos = pos +1
found = False
while (pos+1 < len(msg)) and (not found):
more = msg[pos+1]
for symb in symbols:
if more==symb or more.isdigit():
found = True
break
if found is False:
letter = letter+more
pos = pos + 1
for alphabet in abc.__dict__:
if letter == alphabet:
exec('from sympy.abc import %s'%alphabet)
letters.append(alphabet)
try_expr(expr) # try to evaluate the expression again
import sympy.abc as abc
symbols = ['*','/','(',')',"'"]
letters = [] # for storing any letters that are in the expression
try_expr('2*theta')
我设法从sympy.abc导入了第一个未知变量(无论是单个字母还是像'theta'这样的希腊字母。但是,当我尝试递归调用该函数来查找任何其他未知数时,我设法导入的信件再次被提升为未知。在此过程中,我最终获得RuntimeError : maximum recursion depth exceeded while getting the str of an object
。
答案 0 :(得分:0)
这是代码,带有运行示例
import sympy.abc as abc
symbols = ['*','/','(',')',"'",'"']
letters = []
def try_expr(expr):
try:
for letter in letters:
exec('from sympy.abc import %s'%letter) # re-execute after finding each unknown variable
l = expr.count('(')
r = expr.count(')')
if l == r:
eval(expr)
elif l < r:
eval((r-l)*'('+expr)
except NameError as err:
msg = str(err)
pos = msg.find("'")
letter = msg[pos+1]
pos = pos +1
found = False
while (pos+1 < len(msg)) and (not found): # check for multi-char greek letters
more = msg[pos+1]
for symb in symbols:
if more==symb or more.isdigit():
found = True
break
if found is False:
letter = letter+more
pos = pos + 1
for alphabet in abc.__dict__:
if letter == alphabet:
letters.append(alphabet)
try_expr(expr[expr.find(alphabet):]) # search for the next unknown variable
from sympy import sin, sqrt, log, exp, cos, tanh, sinh, cosh, atan, acos, asin
import sys
if len(sys.argv) == 1:
expr = '(sin(x**2)-log(exp(2*y))) + cos(x**2) + a + b + c + theta*eta'
else:
expr = sys.argv[1]
try_expr(expr)
for letter in letters:
exec('from sympy.abc import %s'%letter)
print 'The SymPy expression %s contains the following letters : %s' %(eval('%s'%expr), letters)
编辑:在分割后对表达式进行评估时,为不平衡的paranthesis添加了修复程序。