【问题标题】:Why does Spyder not pick up a global variable? [duplicate]为什么 Spyder 不选择全局变量? [复制]
【发布时间】:2021-07-18 13:48:16
【问题描述】:

这可能是显而易见的,但我很困惑。

我有一个 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:/Users/Dave/data/Code/Python/lib/test.py', wdir='C:/Users/Dave/data/Code/Python/lib')
1

a = 999

t()
1

FWIW,我正在 Spyder 中运行 iPython。

我认为这很奇怪而不是我应该期待的是否正确?

截图(添加):

【问题讨论】:

  • runfile 是什么?我预计正在发生的事情是 test.py 模块内的 a 遮蔽了您在外部范围中定义的 a
  • @Samwise 我不知道。这是当我在 Spyder IDE 中点击“运行”按钮时打印的内容。 spyder-ide.org
  • 不知道它是如何工作的,我不能肯定地说,但一般来说,你应该避免像这样使用“全局”变量(通常不是真正的全局变量)。它几乎总是令人困惑,而且几乎从来没有让任何事情变得更容易。
  • 我不使用它,但看起来runfile 是 Spyder 特有的东西。它的行为似乎就像它导入了文件一样,因此 ta 位于交互式 shell 的命名空间中,但 t 使用它所在模块的全局 a
  • (这里是 Spyder 维护者) 要在 Spyder 上正确解决这个问题,请查看我上面链接的答案。

标签: python spyder


【解决方案1】:

它们不是同一个变量:

def t():
    print(id(a))

a = 1

t()
>>> runfile('C:/Users/Dave/data/Code/Python/lib/test.py', wdir='C:/Users/Dave/data/Code/Python/lib')
xx

>>> a = 999
>>> print(id(a))
yy

>>> t()
xx

这是runfile 的默认行为。它在不同的命名空间中运行代码。

def runfile(filename=None, args=None, wdir=None, namespace=None, post_mortem=False, current_namespace=False):

如果您想在当前命名空间中运行,请将current_namespace 更改为True

【讨论】:

  • 我想不知何故它们不是同一个变量,否则就不会发生这种情况。但为什么呢?
  • 因为您运行的文件不是在交互式解释器中复制粘贴,而是可能作为模块导入,并且全局变量在模块级别是全局的。因此t 函数使用的a 是其模块中的一个。您可以使用 import <your_module_name> 之类的内容正确导入它 - 但请检查您的目录,并使用 your_module_name.a 引用它。您还可以看到另一个不使用全局变量的理由...
  • @ThierryLathuille 但“t”在交互式命名空间中,那么为什么“a”也不在呢?
  • at 同时导入(因此此时,您的命名空间中的 a 引用了导入模块的 a),但是您创建了一个新的a 在您的命名空间中引用 999(换句话说,您创建了一个值为 999 的整数对象,并让名称 a 引用它。来自导入模块的全局 a 仍然指的是值1)。当您调用t() 时,它会在定义它的模块中查找a,因此它会获取值1
猜你喜欢
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2021-06-20
  • 2019-05-04
  • 1970-01-01
相关资源
最近更新 更多