我在用极品sympy在 python 中生成 ODE 系统的增强系统,以计算状态相对于状态的前向灵敏度。我的目标是优化 ODE 系统。如果我有一个 x1...x10 和参数 a1...a5 的系统,那么增强系统将有 10+10*5 个状态。我的 sympy 代码生成了额外的状态并将它们分配给变量 x1...x60。
后来我在 numpy 中使用集成来解决增强系统。所以我必须编写一个返回 ODE 系统的 rhs() 的函数 - 类似于 this code (如果你们中的一些人是 numpy 的开发人员,请更正 two_springs.py 中的错误,第 29 行 - m2 丢失 )。
我的问题是:我想在函数内部动态分配变量 x1...x_end(状态总数将根据我用于灵敏度的参数数量而变化)。我很兴奋,然后我在 python 中找到了内置的 locals() 函数。来自 this post我认为这应该有效:
def test_l(w, t):
for ii in range(len(w)):
varStr="a%d" % (ii)
locals()[varStr]=w[ii]
return a1*t+a0
w0 = [1.0, 1.0]
t0 = 1.0
f_x=test_l(w0, t0)
print "func res-> %1.4f\n" % (f_x)
运行我得到的脚本 未定义全局名称“a1” .后来我发现 localst() 实际上是 read only .这让我感到困惑的是,如果我使用 调试该功能pde 上 在 ipython ,然后是变量 a1 和 a0 实际上存在于函数内部...使用'pdb on'运行代码我仍然收到错误,程序执行在处停止。返回() ,但 a1 和 a0 实际上存在于函数的工作区中。
ipdb> a1
1.0
ipdb> a0
1.0
为什么 locals() 是只读的,但是在使用 pdb 调试时,实际上可以更改字典?
PS:我以这种方式解决了我的问题:
for ii in range(len(w)):
#varStr="a%d" % (ii)
#locals()[varStr]=w[ii]
varStr="a%d=w[%d]" % (ii, ii)
exec(varStr)
return a1*t+a0
最佳答案
首先让我声明我对 sympy 一无所知。我只看了一眼文档以回应您的评论,即您无法从字典中创建符号...locals()
,正如您所建议的,是只读的。引用 python 文档:
Note The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
我认为这意味着在任何情况下修改它都是不可预测的。因此,如果变量在调试期间处于事件状态,我假设在这些情况下垃圾收集存在差异。或者……不可预测性。
至于sympy中的Symbolic变量。它们似乎只是一个标准的 python 类。这不能从您动态创建的字典中创建 Symbol 对象吗?
from sympy import *
myVars = {'a1':1.0, 'a2':1.0 }
print [Symbol(k) for k in myVars.iterkeys()]
# [a₁, a₂]
在没有更多 sympy 知识的情况下,我并不完全确定这些值的用法,但我相信您可以使用类似的方法做任何需要的事情。动态变量名的需要几乎总是可以通过其他方法解决。
关于python - 调试时python中的locals()字典是只读的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9421758/