即时定义 sympy.abc 个变量:名称错误处理
Defining sympy.abc variables on the fly : name error handling
我正在尝试使用可以包含任何 abc 字母的 eval
SymPy 表达式进行计算:
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 等符号。
另一个重要的问题是表达式中可以有很多不同的字母。我该如何处理?
Edit : 我几乎已经解决了这个问题。
这是我的尝试:
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
.
这是代码,有一个 运行 例子
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)
编辑:添加了对拆分后计算表达式时不平衡括号的修复。
我正在尝试使用可以包含任何 abc 字母的 eval
SymPy 表达式进行计算:
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 等符号。
另一个重要的问题是表达式中可以有很多不同的字母。我该如何处理?
Edit : 我几乎已经解决了这个问题。 这是我的尝试:
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
.
这是代码,有一个 运行 例子
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)
编辑:添加了对拆分后计算表达式时不平衡括号的修复。