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

问题描述 投票:0回答:1

我无法在Python 3.8,Windows 10的Spyder 4.0.0中交互修改全局变量。必须有一个最近的更改,因为以前可以这样做。

我有以下示例文件:

x = 5
def IncreaseX():
    global x
    x += 1

print(x)
IncreaseX()
print(x)
  1. [当我使用F5运行它时,我得到了期望的输出:
In [1]: runfile('TestGlobals.py', wdir='D:')
5
6
  1. 但是,如果我尝试从嵌入式Ipython控制台运行GrowthX()函数,它不会更改全局变量的值:
In [2]: x
Out[2]: 6

In [3]: IncreaseX()

In [4]: x
Out[4]: 6
  1. 如果我选择示例的最后三行,并且运行它们(使用F9),也会发生同样的情况:
In [5]: print(x)
   ...: IncreaseX()
   ...: print(x)
6
6
  1. 如果我选择示例文件的所有行并运行它们(使用F9),则行为会有所不同:
In [6]: x = 5
   ...: def IncreaseX():
   ...:     global x
   ...:     x += 1
   ...: 
   ...: print(x)
   ...: IncreaseX()
   ...: print(x)
5
6
  1. 完成此操作后,我可以修改全局变量的值。重复步骤2的完全相同的代码,我得到了所需的结果:
In [7]: x
Out[7]: 6

In [8]: IncreaseX()

In [9]: x
Out[9]: 7

有人了解这种行为吗?如何恢复旧的行为(即具有第2步,可以直接作为第5步工作?)?

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

python function spyder interactive globals
1个回答
0
投票

[您似乎对Python的“全局”变量的定义非常困惑-并且您实际上并不是唯一的变量,因为它与通常的定义xD完全不同)>

在大多数语言中,“全局”表示“全局进程”-由所有模块/函数/当前进程使用的任何变量共享的变量。]​​>

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

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

[请注意,从x导入mymodule也无法按预期方式进行-仅在导入模块中使用初始值x创建一个新的mymodule.x,但这些名称仍然完全不相关,并重新绑定一个不会重新绑定另一个:

broken2.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的“变量”真正是什么以及它们为什么如此工作的更多说明,您一定要阅读Ned Batchelder's reference article here

© www.soinside.com 2019 - 2024. All rights reserved.