调试时python中的locals()命令是只读的吗?

调试时python中的locals()命令是只读的吗?,python,debugging,namespaces,scope,variable-assignment,Python,Debugging,Namespaces,Scope,Variable Assignment,我正在使用python中的Wonder生成ODE系统的增强系统,以计算状态对状态的前向灵敏度。我的目标是优化ODE系统。如果我有一个x1…x10的系统和参数a1…a5,那么扩充系统将有10+10*5个状态。我的sympy代码生成额外的状态并将它们分配给变量x1…x60 后来我使用numpy中的集成来解决增强系统。因此,我必须编写一个函数,返回ODE系统的rhs(),类似于(如果你们中的一些人是numpy的开发人员,请更正two_springs.py中的错误,第29行-m2缺失) 我的问题是:我想

我正在使用python中的Wonder生成ODE系统的增强系统,以计算状态对状态的前向灵敏度。我的目标是优化ODE系统。如果我有一个x1…x10的系统和参数a1…a5,那么扩充系统将有10+10*5个状态。我的sympy代码生成额外的状态并将它们分配给变量x1…x60

后来我使用numpy中的集成来解决增强系统。因此,我必须编写一个函数,返回ODE系统的rhs(),类似于(如果你们中的一些人是numpy的开发人员,请更正two_springs.py中的错误,第29行-m2缺失)

我的问题是:我想在一个函数中动态地分配变量x1…x_end(状态的总数将根据我用于灵敏度的参数数量而变化)。我很激动,然后在python中找到了内置的locals()函数。从那时起,我认为这应该奏效:

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()实际上是。这让我感到困惑的是,如果我在ipython中调试函数时启用pde,那么变量a1a0实际上存在于函数内部。。。在“pdb开启”的情况下运行代码,我仍然会收到一个错误,程序执行会在返回()处停止,但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文档:

注:本词典内容不得修改;变化 可能不会影响应用程序使用的本地变量和自由变量的值 翻译

我认为这意味着在任何情况下修改它都是不可预测的。因此,如果在调试过程中变量是活动的,我假设在这些情况下垃圾收集是不同的。或不可预测性

至于symphy中的符号变量。它们似乎只是一个标准的python类。从动态创建的dict创建符号对象不是很有效吗

from sympy import *
myVars = {'a1':1.0, 'a2':1.0 }
print [Symbol(k) for k in myVars.iterkeys()]
# [a₁, a₂]

如果没有更多的Symphy知识,我不能完全确定这些值的用法,但是我相信您可以使用类似的方法来做任何需要做的事情。动态变量名的需求通常可以通过其他方法解决。

Python文档中警告不要写入jdi提到的
locals()
,原因是大多数时候,您在
locals()中更改的内容
不要传播回实际的局部变量。这是因为当地人可以来自不止一个地方。之所以
locals()

在某些情况下,向
locals()返回的字典写入内容时会起作用。如果在函数中的任何位置包含
exec
语句,即使它从未执行过(即在
return
语句之后),写入
locals()
也会起作用。然而,局部变量的速度会比其他变量慢,因为Python在“编译”时不知道所有局部变量的名称时,无法使用“快速”操作码通过索引访问局部变量

def foo(val):    # circuitously returns value passed in
    locals["b"] = val
    return b
    exec ""
此外,您还会发现闭包(内部和外部函数之间共享变量)不起作用

def foo(a):   # can't define this function
    def bar():
       return a
    return bar
    exec ""
我相信,当跟踪函数处于活动状态时,Python解释器对
locals()


这都是针对CPython的;Jython和IronPython的行为可能不同。

为什么,为什么要动态创建这些变量?这有一个原因,在Python中,这类问题不像在其他一些语言中那么容易。我在这里不止一次看到过这种问题,关于有人试图创建动态命名的变量,并且总是以错误地处理问题而告终。“真的没有很好的理由这么做。”NiklasB。因为如果我改变参数的数量,那么我会得到一个不同长度的状态向量。我希望状态向量的长度能够自我调整,所以我不必关心这个问题。但是,如果您已经知道要访问的变量名,为什么不使用普通字典呢?为什么你需要它们是你没有句柄的匿名变量?@Ivan Angelov:你可以做一些类似于
d={'a%d'%i:sympy.var('a%d'%i')的事情,比如xrange(100)中的i;d['a78']+d['a98']
。有什么问题吗?您描述的关于使用
locals()
的差异可能是由于不同的Python版本造成的。它不是用来写的,所以它不能像你期望的那样工作也就不足为奇了。我经常发现自己写的东西像
xx=[Symbol(“x%d”%I)代表范围(10)内的I]
,然后
f=sum(c*x代表c,zip中的x(coefs,xx))
等等。使用列表比dict有一些优势,因为它使排序更容易,但是YMMV。我从来都不需要攻击当地人()。是的,就像我刚才说的,我真的不知道sympy。所以我不确定他需要创建的实际对象是什么。但不管w是什么,理论都是一样的