Python 如何使全局变量在函数内部的Spyder中工作?
我无法在Spyder 4.0.0中使用Python 3.8和Windows 10交互修改全局变量。 一定是最近发生了变化,因为这在以前是可能的 我有以下示例文件:Python 如何使全局变量在函数内部的Spyder中工作?,python,function,spyder,interactive,globals,Python,Function,Spyder,Interactive,Globals,我无法在Spyder 4.0.0中使用Python 3.8和Windows 10交互修改全局变量。 一定是最近发生了变化,因为这在以前是可能的 我有以下示例文件: x = 5 def IncreaseX(): global x x += 1 print(x) IncreaseX() print(x) 当我运行它(使用F5)时,我会得到所需的输出: 但是,如果我尝试从嵌入式Ipython控制台运行IncreaseX()函数,它不会更改全局变量的值: 如果选择示例的最后3行并运行
x = 5
def IncreaseX():
global x
x += 1
print(x)
IncreaseX()
print(x)
找到了强> Spyder/Preferences/Run/General settings/Run在控制台的命名空间中运行,而不是在空命名空间中运行
启用此选项后,globals的旧行为将恢复。看起来您对Python关于“全局”变量的定义(相当特殊)感到困惑,实际上您不是唯一一个,因为它与通常的定义xD有很大不同 在大多数语言中,“global”表示“processglobal”-一个由当前进程使用的所有模块/函数/任何东西共享的变量 Python没有真正的“进程全局”范围,“全局”实际上意味着“模块级”——每个模块都是它自己的名称空间,模块中的全局实际上只是该模块中的“全局”。在使用模块的代码中,必须将此变量称为“yourmodulename.x” 一个简短的例子可能有助于 mymodule.py:
x = 1
def inc():
global x # within this module, this refers to `mymodule.x`, not any other 'x'
x += 1
def show():
# no need for the global kw if it's only for reading
print("in mymodule, x = {}".format(x))
working.py:
import mymodule
print("mymodule.x before: {}".format(mymodule.x))
mymodule.show()
mymodule.inc()
print("mymodule.x after: {}".format(mymodule.x))
mymodule.show()
Brokern1.py:
import mymodule
# this 'x' belongs to broken1, and `mymodule` isn't even
# aware it exists...
x = 42
print("broken1.x before: {}".format(x))
mymodule.show() # setting broken1.x to 42 didn't change mymodule
mymodule.inc()
# our own 'x' has not changed
print("broken1.x after: {}".format(x))
# but mymodule.x did
mymodule.show()
请注意,从mymodule
导入x
也不会像预期的那样工作-它只会在导入模块中创建一个新的x
,初始值为mymodule.x
,但这些名称仍然完全不相关,重新绑定一个不会重新绑定另一个:
brokern2.py:
from mymodule import x
from mymodule import inc, show
print("broken2.x before: {}".format(x))
show() # so far we have the same values, BUT:
inc() # this rebinds mymodule.x but has no impact here
# our own 'x' has not changed
print("broken2.x after: {}".format(x))
# but mymodule.x did
show()
关于Python的“变量”到底是什么以及为什么它们会这样做的更多解释,您一定要阅读
因此,解决问题的方法很简单,就是始终使用mymodule.x
(当然,在mymodule
之外):
working2.py:
import mymodule
mymodule.show()
mymodule.inc()
mymodule.show()
mymodule.x = 666
mymodule.show() # gives the expected result
# let's go to 667
mymodule.inc()
mymodule.show()
()这会有用吗?(此处为Spyder maintainer)很抱歉造成混淆,但我们更改了默认的评估模式,因为它对初学者更安全,并且避免了再现性问题,因为不依赖以前的结果。@CarlosCordoba我理解你的观点,但我担心许多用户可能会发现自己的代码有问题。Spyder的一个优点(与Matlab类似)是变量可以从控制台以正方方式打印/更改:这对于科学目的非常方便,比如读取测量仪器/绘制数据。在第一次启动SPYDER 4时,您可能需要考虑清楚地解释弹出窗口中的这种变化。感谢您(和其他开发人员)的出色工作!不幸的是,人们不看弹出窗口,但谢谢你的建议。我们看看会发生什么。此外,在新版本中执行代码后,可以在控制台中修改变量。问题是,除非您将更改移动到编辑器中,否则下次重新运行代码时将无法获取它们。非常感谢您的详细回复!我不知道这种“模块全局”行为。但是,这不是我的问题,因为我没有运行任何导入。我在Spyder中找到了想要的选项[我更新了上面的帖子],他们一定是最近才添加的。再次感谢您的解释!
x = 1
def inc():
global x # within this module, this refers to `mymodule.x`, not any other 'x'
x += 1
def show():
# no need for the global kw if it's only for reading
print("in mymodule, x = {}".format(x))
import mymodule
print("mymodule.x before: {}".format(mymodule.x))
mymodule.show()
mymodule.inc()
print("mymodule.x after: {}".format(mymodule.x))
mymodule.show()
import mymodule
# this 'x' belongs to broken1, and `mymodule` isn't even
# aware it exists...
x = 42
print("broken1.x before: {}".format(x))
mymodule.show() # setting broken1.x to 42 didn't change mymodule
mymodule.inc()
# our own 'x' has not changed
print("broken1.x after: {}".format(x))
# but mymodule.x did
mymodule.show()
from mymodule import x
from mymodule import inc, show
print("broken2.x before: {}".format(x))
show() # so far we have the same values, BUT:
inc() # this rebinds mymodule.x but has no impact here
# our own 'x' has not changed
print("broken2.x after: {}".format(x))
# but mymodule.x did
show()
import mymodule
mymodule.show()
mymodule.inc()
mymodule.show()
mymodule.x = 666
mymodule.show() # gives the expected result
# let's go to 667
mymodule.inc()
mymodule.show()