Python 如何使全局变量在函数内部的Spyder中工作?

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行并运行

我无法在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行并运行它们(使用F9),也会发生同样的情况:
  • 如果我选择示例文件的所有行并运行它们(使用F9),则行为会有所不同:
  • 完成此操作后,我可以修改全局变量的值。 重复步骤2的完全相同的代码,我获得了期望的结果:
  • 有人了解这种行为吗?如何恢复旧的行为(即,让步骤2直接作为步骤5工作)

    我知道使用全局变量通常是非常糟糕的。 然而,当我控制一个实验时,我需要交互式地修改一些变量,因此一些正确工作的全局变量大大简化了我的工作流程


    找到了

    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()