在函数内部定义之前使用'global'关键字会发生什么?

时间:2019-10-18 22:53:03

标签: python

我是Python的初学者,最近刚遇到'global'关键字。我了解“全局”更改变量范围的基本用法,但我想知道为什么以下代码不起作用:

def foo():
    global y
    print('y inside foo is', y)

foo()
print('global y is', y)

我认为它会输出一些空变量(如None),但是它给出:

NameError: name 'y' is not defined

我尝试过:

def foo():
    global y
    y = 1
    print('y inside foo is', y)

foo()
print('global y is', y)

这给出了:

y inside foo is 1
global y is 1

这是可以预期的,因为我们首先声明一个全局变量y,然后为其分配1,因此我们在globals()中找到它。

另一个问题是:

def foo():
    def bar():
        print(locals())
        print(y)
    y = 1
    bar()
foo()

给予:

{'y': 1}
1

因为在bar()内部,我们只有一个局部变量“ y”。

但是当我将其更改为以下内容时,局部变量“ y”就消失了:

def foo():
    def bar():
        print(locals())
        y = y + 1
        print(y)
    y = 1
    bar()
foo()

print(locals())输出{},我不明白为什么。

3 个答案:

答案 0 :(得分:0)

您永远不会定义y来实际包含一个值。在Python中,尝试访问没有值的变量将引发NameError,您将在此处看到。您可以初始化变量以开始(以None或其他一些首选的默认值),然后在文件的其余部分使用它,如下所示:

y = None
def foo():
    global y
    print('y inside foo is', y)

foo()
print('global y is', y)
  foo内部的

y是None
  全局y为无

答案 1 :(得分:0)

示例1:Python中什么是“空变量”?您从未定义y;你被打了。

示例2:您了解

示例3:不,bar没有 具有局部变量y。由于没有内容,它将在其上下文堆栈中向外搜索,并在下一个名称空间y中找到foo

示例4:locals实际上为空。 y对于foo是本地的,而不是bar。但是,您的增量语句出错,因为尝试更改y意味着您拥有一个global y(您没有),或者您正在定义一个新的。因此,RHS y必须是本地的-但尚未定义,您会再次受到打击。

答案 2 :(得分:0)

Python创建扫描其正文的函数时,每件事都会发生:

def foo():
    def bar():
        print(locals())  # P is not present
        print(y)
        print(y)
        x = 5
        print(locals())  # after initializing x is added to local
    y = 1
    p = 1
    # ('x',) local variables
    print(bar.__code__.co_varnames)
    # ('y',)  non local variables used by the function
    print(bar.__code__.co_freevars)
    bar()
foo()

Python发现bar使用了y,但是它在body函数的任何地方都没有初始化,所以它是co_freevars

  

co_freevars:自由变量名称的元组(通过a引用   功能关闭

在关联表达式左侧的其他变量是co_varnames

  

co_varnames:参数名称和局部变量的元组

当您使用global时,您将告诉Python这不是局部变量,以及何时 您可以更改它的值,可以在定义函数而不是调用函数的全局空间中更改它。

def foo():
    global y  # assumes that y exist in the current module
    y = 5  # when you change it's value it change the value of y in the current module

# even that we used `y` in a left side of assignment expression is not added as local variable
print(foo.__code__.co_varnames)

当您在未定义变量foo的模块中定义y时,foo不会在该模块的全局范围内找到该变量,这就是为什么您得到: NameError: name 'y' is not defined

要了解更多有关角色global关键字的信息,请检查以下内容:

def foo():
    global y
    y = 1  # this set the variable in the scope of module not the scope of this function
    print('y' in locals())  # False it's not a local variable of this method


print('y' in globals())  # False
foo()
print('y' in globals())   # True