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

2024-03-29 02:06:38 发布

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

我是Python的初学者,最近刚遇到“global”关键字。我理解“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())输出{},我不明白为什么。你知道吗


Tags: 代码none用法fooisdefbar关键字
3条回答

例1:Python中的“空变量”是什么?你从来没有定义过y;你被打了。你知道吗

例2:你明白吗

例3:否,bar有局部变量y。由于没有,它向外搜索上下文堆栈,并在下一个名称空间foo中找到y。你知道吗

例4:locals实际上是空的。y是本地的foo,而不是bar。但是,您的increment语句会出错,因为尝试更改y意味着您有一个global y(您没有),或者您正在定义一个新的。因此,RHSy必须是本地的,但尚未定义,因此您将再次受到攻击。你知道吗

您从不将y定义为实际包含值。在Python中,试图访问一个没有值的变量会抛出一个NameError,您可以在这里看到。您可以初始化变量以开始(使用None或其他首选的默认值),然后在文件的其余部分使用它,如下所示:

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

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

y inside foo is None
global y is None

当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 : tuple of names of free variables (referenced via a function’s closure

位于assiegment表达式左侧的其他变量是co_varnames

co_varnames : tuple of names of arguments and local variables

当您使用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)

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

要进一步了解roleglobal关键字,请检查以下内容:

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

相关问题 更多 >