【问题标题】:How to change global variables using globals() in python method?如何在 python 方法中使用 globals() 更改全局变量?
【发布时间】:2018-02-10 08:30:08
【问题描述】:

如果我有以下 Python 脚本 foo.py :

def foo() :
  my_dict = {'A': 1, 'B': 2, 'C': 3}
  globals().update(my_dict)
  print(A)
  print(B)
  print(C)

foo()

我可以在 ipython 中输入这个:

run foo.py
=> 1
=> 2
=> 3
A
=> 1

但是,如果我删除底部的 foo() :

def foo() :
  my_dict = {'A': 1, 'B': 2, 'C': 3}
  globals().update(my_dict)
  print(A)
  print(B)
  print(C)

# no foo

然后我在 ipython 中输入:

run foo.py
foo()
=> 1
=> 2
=> 3
A
=> NameError: name 'A' is not defined

我收到此错误。为什么会这样?

【问题讨论】:

  • 你能举个element_dict的例子吗
  • @PratikKumar {'H': 1.0, 'He': 4.0, 'C': 12.0}
  • @PratikKumar 我会把问题改成更容易理解的
  • @PratikKumar 更新了!
  • print('A') 会打印一个 A,而不是 1。提问时,请发布您实际运行的代码以及运行它得到的实际输出。

标签: python dictionary global-variables ipython


【解决方案1】:

IPython 的%run 默认在新命名空间中运行文件,然后将结果复制到您的命名空间中。

foo.py 包含foo() 调用时,会在新命名空间中创建ABC 变量,然后IPython 会将这些变量复制到您的命名空间。

foo.py 不包含foo() 调用时,您可以自己调用foo(),但foo 仍将其原始命名空间用于全局变量。调用 foo() 会在 foo 的原始命名空间中创建 ABC 变量,对于 IPython 来说太迟了,无法将它们拾取并将它们复制到您的命名空间中。

您可以使用%run-i 标志直接在您的命名空间中运行文件,避免这些问题。

【讨论】:

    【解决方案2】:

    您需要在分配之前声明element_dict 一个全局变量。一旦你在一个函数中有一个赋值语句anywhere,除非另有说明,否则被赋值的变量只在局部范围内声明。在您的情况下,由于element_dict = read_mass_from_file()element_dict 在本地声明。

    See the documentation for more details.

    要实际引用全局变量:

    def mass_mode() :
      '''
      Add element names and masses to the global variables.
      '''
      global element_dict
      element_dict = read_mass_from_file()
    

    将从全局范围更新element_dict

    【讨论】:

    • 感谢您的回答!我刚刚编辑了这个问题。你如何看待这个新问题?答案还是一样吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2014-11-23
    • 1970-01-01
    • 2018-09-19
    • 2020-03-17
    • 2013-06-22
    相关资源
    最近更新 更多