【问题标题】:Using globals in Python exec在 Python exec 中使用全局变量
【发布时间】:2016-06-18 04:30:40
【问题描述】:

我正在尝试创建一个自定义 python 解释器类型的应用程序。我正在使用 exec 语句(在 Python 2.7.6 中)来执行给定的代码,但全局变量并没有像预期的那样工作。有人可以解释为什么这不起作用:

def print_x():
    print(x)


g = {'x': 10, 'print_x': print_x}
l = {}

exec('print_x()', g, l)

结果(无论print_x函数是g还是l),都是错误的:

NameError: global name 'x' is not defined

那么,传递给 exec 的全局变量不会传递给被调用的函数吗?

【问题讨论】:

  • 所以 exec 不知道如何解析你的字典 g
  • 但我可以使用 exec('print(x)', g, l) 就好了。它只是不适用于 print_x 函数。
  • stackoverflow.com/questions/2904274/… - 似乎与您的情况相似
  • 感谢您提供该链接。它与我的程序相似但不完全相同。我现在尝试在 print_x() 函数中打印出 globals() 和 locals() ,果然,'x' 不存在。我只是不太清楚为什么会这样。

标签: python


【解决方案1】:

函数内部的x 是从定义函数的命名空间的全局变量中提取的。但是,您在不同的命名空间中调用它。这与拥有多个模块没有太大区别:

# foo.py
def print_x():
    print(x)

然后尝试在不同的模块中使用它:

# bar.py
from foo import print_x

x = 10
print_x()  # NameError

最终,gexec 执行上下文中的全局变量。在它调用print_x 函数(在不同的全局上下文中定义)之后,你不能指望print_x 知道有关exec 执行上下文中的全局变量的任何信息——print_x 只知道它的模块上下文中的全局变量.

【讨论】:

  • 好的,谢谢。那么,我需要使用 exec 定义 print_x() 函数吗?有没有其他方法可以改变函数的命名空间?
  • @jordanwh 如果您真的想更改全局变量,您可以创建一个 copy of the function,并为新函数全局变量传递您自己的范围。
  • @jordanwh -- 我想我已经看到了一些(可能是 cpython 特定的)解决方案,它们使用 types.FunctionType 或类似的东西从旧的函数中创建了一个新函数。我不知道该怎么做,所以如果你真的想让它发挥作用,你可能需要做一些调查......
  • @Tadhg McDonald-Jensen 完美。谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-08-04
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
  • 2016-10-07
相关资源
最近更新 更多