Python何时在本地scop中创建名称记录

2024-09-27 09:32:38 发布

您现在位置:Python中文网/ 问答频道 /正文

这个问题不是关于解决这个问题,而是关于理解Python(2.7)编译器部分的内部工作原理。你知道吗

请参见下面的代码。它是一个标准的decorator函数,其参数去掉了所有花哨的东西。你知道吗

def deco(basedir):
  def wrap(f):
    def newf(*args, **kwargs):
      if basedir == "":          # local or nested?
        basedir="empty"          # local scope
      print basedir              # local or nested?
      return f(*args, **kwargs)
    return newf
  return wrap

@deco(basedir="full")
def test1(a):
  print a

if __name__ == "__main__":
  test1("test1")

当您测试它时,它会失败,并在if basedir==”“:行上的赋值之前引用局部变量'basedir'。请注意,在本例中,条件体(赋值)从未执行。你知道吗

但是当您用下面的代码片段替换if时,它会突然起作用。你知道吗

if basedir == "":
  base = "empty"
else:
  base = basedir
print base

当解释器遇到赋值时,我希望失败的情况会创建一个局部变量basedir,但是在if语句中使用父变量的作用域。但在我看来,当代码中存在basedir=赋值时,它也会尝试在if中使用局部变量。你知道吗

那么有谁能解释一下Python编译器是如何在这种情况下创建名称的呢?本地范围是在编译时预先准备的吗?当编译器看到对局部变量的赋值时,它是否用一个未定义的值预先初始化名称?你知道吗

你知道这种行为在哪里有记录吗?你知道吗

我知道以前这里也解决过类似的问题,但我不是在寻求解决办法。我想看看解释,最好是一个指向文档的指针。你知道吗

有关: "local variable referenced before assignment" — only functions?


Tags: 代码basereturnif编译器localdefprint
2条回答

问题是Python编译器无法确定basedir的正确作用域。Python中的作用域是静态确定的。但是basedir="empty"赋值语句使basedir变量成为newf函数的局部变量。因此,您不能在第一次赋值之前访问局部变量。你知道吗

至于您的“fix”,您刚刚删除了basedir="empty"的赋值,basedir对于newf不是更局部的,而是使用from deco函数。你知道吗

在Python 2中,只能全局或局部设置变量,不能嵌套:

global_variable_that_is_global = 1
global_variable_that_is_only_used_locally = 2

def function():
    nested_variable_that_can_not_be_set_by_inner_functions = 3
    def inner_function():
        global global_variable_that_is_global
        global_variable_that_is_global = "changed"
        global_variable_that_is_only_used_locally = "changed"
        nested_variable_that_can_not_be_set_by_inner_functions = "changed"

    def get_nested_variable():
        return nested_variable_that_can_not_be_set_by_inner_functions

    return inner_function, get_nested_variable

执行此操作时,可以尝试以下操作:

>>> inner_function, get_nested_variable = function()
>>> get_nested_variable()
3
>>> inner_function()
>>> get_nested_variable()
3
>>> global_variable_that_is_only_used_locally
2
>>> global_variable_that_is_global
'changed'

因此,与Python2不同的是,Python3中有一个非本地关键字:

>>> def function():
    nonlocal_variable = 1
    def inner_function():
        nonlocal nonlocal_variable
        nonlocal_variable = "changed"
    def get_nonlocal_variable():
        return nonlocal_variable
    return inner_function, get_nonlocal_variable

>>> inner_function, get_nonlocal_variable = function()
>>> get_nonlocal_variable()
1
>>> inner_function()
>>> get_nonlocal_variable()
'changed'

相关问题 更多 >

    热门问题