程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了python exec()中的全局变量和局部变量大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决python exec()中的全局变量和局部变量?

开发过程中遇到python exec()中的全局变量和局部变量的问题如何解决?下面主要结合日常开发的经验,给出你关于python exec()中的全局变量和局部变量的解决方法建议,希望对你解决python exec()中的全局变量和局部变量有所启发或帮助;

好吧,我认为这可能是实现错误,也可能是未经证明的设计决策。问题的症结在于模块范围内的名称绑定操作应绑定到全局变量。实现的方式是,在模块级别,globals()是locals()(在解释器中尝试该值),因此,当您进行任何名称绑定时,它会像往常一样将其分配给locals( )字典,它也是全局变量,因此创建了全局变量。

查找变量时,首先检查当前的本地变量,如果未找到名称,则递归检查包含范围的本地变量变量名称,直到找到变量或到达模块作用域为止。如果达到此目的,则检查全局变量,该全局变量应该是模块作用域的本地变量。

>>> exec(compile("import sys\nprint sys._getframe().f_code.co_name", "blah", "exec"), {}, {})
<module>
>>> exec("a = 1\nclass A(object):\n\tprint a\n", {}, {})
TraceBACk (most recent call last):
  file "<stdin>", line 1, in <module>
  file "<String>", line 2, in <module>
  file "<String>", line 3, in A
nameError: name 'a' is not defined
>>> d = {}
>>> exec("a = 1\nclass A(object):\n\tprint a\n", d,d)
1

此行为是继承起作用的原因(名称查找使用了代码对象的作用域locals(),其中确实包含A)。

最后,这是cpython实现中的一个丑陋的骇客,专门用于对全局变量进行查找。它还会导致一些荒谬的人为情况-例如:

>>> def f():
...     global a
...     a = 1
...
>>> f()
>>> 'a' in locals()
True

请注意,这是我在阅读python语言参的第4.1节(命名和绑定)时基于与解释器混淆的所有推断。尽管这不是确定的(我还没有打开cpython的源代码),但我相当确定我对行为是正确的。

解决方法

我正在尝试使用exec运行一段python代码。

@H_686_7@my_code = """
class A(object):
  pass

print 'locals: %s' % locals()
print 'A: %s' % A

class B(object):
  a_ref = A
"""

global_env = {}
local_env = {}
my_code_AST = compile(my_code,"My Code","exec")
exec(my_code_AST,global_env,local_env)

print local_env

这导致以下输出

locals: {'A': <class 'A'>}
A: <class 'A'>
TraceBACk (most recent call last):
  File "python_test.py",line 16,in <module>
    exec(my_code_AST,local_env)
  File "My Code",line 8,in <module>
  File "My Code",line 9,in B
NameError: name 'A' is not defined

但是,如果我将代码更改为此-

@H_686_7@my_code = """
class A(object):
  pass

print 'locals: %s' % locals()
print 'A: %s' % A

class B(A):
  pass
"""

global_env = {}
local_env = {}
my_code_AST = compile(my_code,local_env)

print local_env

然后工作正常-提供以下输出-

locals: {'A': <class 'A'>}
A: <class 'A'>
{'A': <class 'A'>,'B': <class 'B'>}

显然,A存在并且可以访问-在第一段代码中出了什么问题?我正在使用2.6.5,欢呼声,

科林

更新1

如果我检查类中的locals()-

@H_686_7@my_code = """
class A(object):
  pass

print 'locals: %s' % locals()
print 'A: %s' % A

class B(object):
  print locals()
  a_ref = A
"""

global_env = {}
local_env = {}
my_code_AST = compile(my_code,local_env)

print local_env

然后很明显,locals()在两个地方都不相同-

locals: {'A': <class 'A'>}
A: <class 'A'>
{'__module__': '__builTin__'}
TraceBACk (most recent call last):
  File "python_test.py",line 10,in B
NameError: name 'A' is not defined

但是,如果我这样做,就没有问题-

def f():
  class A(object):
    pass

  class B(object):
    a_ref = A

f()

print 'Finished OK'

更新2

好的,所以这里的文档-http:
//docs.python.org/reference/executionmodel.html

“类定义是可以使用和定义名称的可执行语句。 这些参遵循名称解析的常规规则。类定义的名称空间成为该类的属性字典。在类范围内定义的名称在方法中不可见

在我看来,“
A”应作为可执行语句(作为B的定义)中的自由变量提供,并且这种情况在我们调用上面的f()时发生,但在使用exec()时不发生。使用以下代码可以更容易地显示出来:

@H_686_7@my_code = """
class A(object):
  pass

print 'locals in body: %s' % locals()
print 'A: %s' % A

def f():
  print 'A in f: %s' % A

f()

class B(object):
  a_ref = A
"""

哪个输出

locals in body: {'A': <class 'A'>}
A: <class 'A'>
TraceBACk (most recent call last):
  File "python_test.py",line 20,line 11,in f
NameError: global name 'A' is not defined

因此,我想一个新的问题是-为什么这些局部变量不会在函数和类定义中作为自由变量公开-似乎是一个非常标准的关闭方案。

大佬总结

以上是大佬教程为你收集整理的python exec()中的全局变量和局部变量全部内容,希望文章能够帮你解决python exec()中的全局变量和局部变量所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。