Python 为什么Spyder不选择全局变量?
这可能是显而易见的,但我很困惑 我有一个Python脚本test.py:Python 为什么Spyder不选择全局变量?,python,spyder,Python,Spyder,这可能是显而易见的,但我很困惑 我有一个Python脚本test.py: def t(): print(a) a = 1 t() 当我运行它时,它会按预期打印1: runfile('C:/Users/Dave/data/Code/Python/lib/test.py', wdir='C:/Users/Dave/data/Code/Python/lib') 1 但当我以交互方式键入“a=999”并再次运行t()时,我希望它打印999。但它打印的是1。为什么? runfile('C:
def t():
print(a)
a = 1
t()
当我运行它时,它会按预期打印1:
runfile('C:/Users/Dave/data/Code/Python/lib/test.py', wdir='C:/Users/Dave/data/Code/Python/lib')
1
但当我以交互方式键入“a=999”并再次运行t()时,我希望它打印999。但它打印的是1。为什么?
runfile('C:/Users/Dave/data/Code/Python/lib/test.py', wdir='C:/Users/Dave/data/Code/Python/lib')
1
a = 999
t()
1
FWIW,我在Spyder内部运行iPython
我认为这很奇怪,而不是我所期望的,对吗
截图(新增):
它们不是相同的变量:
def t():
print(id(a))
a = 1
t()
这是
runfile
的默认行为。它在不同的名称空间中运行代码
def runfile(filename=None, args=None, wdir=None, namespace=None, post_mortem=False, current_namespace=False):
如果要在当前命名空间中运行,请将
当前\u命名空间
更改为True
。什么是运行文件
?我想发生的事情是,test.py
模块中的a
将您在外部范围中定义的a
隐藏起来。@Samwise我不知道。这是我在Spyder IDE中点击“运行”按钮时打印的内容。在不知道它到底是如何工作的情况下,我无法确定,但一般来说,您应该避免使用这样的“全局”变量(通常不是真正的全局变量)。它几乎总是让人困惑,而且几乎不会让任何事情变得更简单。我不使用它,但它看起来像是Spyder特有的runfile
。它的行为好像导入了文件,因此t
和a
位于交互式shell的名称空间中,但是t
使用它所属模块的全局a
(此处为Spyder维护者)在Spyder上正确解决此问题,请看我上面链接的答案。我想它们不是同一个变量,否则就不会发生这种情况。但是为什么呢?因为您运行的文件不是复制粘贴到交互式解释器中的,而是作为模块导入的,并且全局变量在模块级别是全局的。因此,t
函数使用的a
是其模块中的一个。您可以使用类似于import
的方法正确地导入它,但请检查目录,并使用您的模块名称来引用它。您可以看到不使用全局变量的另一个原因…@thierrylahuille但“t”在交互名称空间中,那么为什么“a”不也在交互名称空间中?a
与t
同时被导入(所以此时,您名称空间中的a
引用了导入模块的a
),但是,您在命名空间中创建了一个新的a
,它引用999
(换句话说,您创建了一个值为999
的整数对象,并使名称a
引用它。导入模块中的全局a
仍然引用值1
)。调用t()
时,它会在定义它的模块中查找a
,因此它会得到值1
。
def runfile(filename=None, args=None, wdir=None, namespace=None, post_mortem=False, current_namespace=False):