为啥执行 exec('print(x)') 而 print(x) 在此 python 代码中出错?
Posted
技术标签:
【中文标题】为啥执行 exec(\'print(x)\') 而 print(x) 在此 python 代码中出错?【英文标题】:why exec('print(x)') is executed while print(x) goes wrong in this python code?为什么执行 exec('print(x)') 而 print(x) 在此 python 代码中出错? 【发布时间】:2021-04-02 02:51:12 【问题描述】:def build(s, loc):
exec(s, loc)
return loc
def main():
L = build('x = 1', locals())
locals().update(L)
exec('print(x)')
if __name__ == '__main__':
main()
当我运行上面的代码时,python 控制台会显示 '1'。
def build(s, loc):
exec(s, loc)
return loc
def main():
L = build('x = 1', locals())
locals().update(L)
print(x)
if __name__ == '__main__':
main()
当我运行上面的代码时,它会显示'name 'x' is not defined'。
它们有什么区别?
我修改了代码以减少歧义,但仍然存在类似问题。
def main():
exec('x = 1')
exec('print(x)')
if __name__ == '__main__':
main()
这将显示“1”。
def main():
exec('x = 1')
print(x)
if __name__ == '__main__':
main()
这会出错。
【问题讨论】:
修改locals
是未定义的行为。
感谢您的回答。我添加更多细节,类似的错误仍然存在。
用exec
修改局部变量也是未定义的行为。
我假设它可能是解释器不理解exec('x = 1')
实例化了一个新变量x
,因此错误地假设您的第二个代码在执行前校对它时包含语法错误 - 而它应该可以正常运行,因此当通过 exec
调用调用 x 时,在您的第一个示例中通过语法检查就好了
【参考方案1】:
这与范围有关。
当这样做时:
def main():
exec('x = 1')
print(x)
if __name__ == '__main__':
main()
exec 定义的 x 变量是局部的,与传递给 print() 函数的 x 变量不同,后者是全局的。除非你告诉它:
def main():
exec('global x;x = 1')
print(x)
if __name__ == '__main__':
main()
这最终对我有用,它打印 1。
这是因为在 exec() 中对 x 变量使用 global
关键字后,您告诉解释器尽管在本地范围内,对 x 变量的任何进一步引用都将引用外部,全局,x变量。
【讨论】:
感谢您的回答。但是如果我将 main() 函数修改为:def main():x =1;print(locals()['x']);print(x),它会打印 '1/n1'。这意味着 x 仍然是一个局部变量,即使 x 由 x = 1 定义。如果将 main() 修改为: def main():x=1;print(globals()['x'];print(x)) ,就会发生KeyError。以上是关于为啥执行 exec('print(x)') 而 print(x) 在此 python 代码中出错?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Runtime.getRuntime().exec(startupOracle);没有完全执行命令