繁体   English   中英

在 function 中定义之前使用“全局”关键字会发生什么?

[英]What happens when using 'global' keyword before defining inside a function?

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

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()) 输出 {},我不明白为什么。

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

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

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

foo 里面的 y 是 None
全局 y 为无

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

例二:你懂的

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

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

当 Python 创建 function 它扫描它的身体时,每件事都会发生:

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但它没有在主体 function 的任何点初始化,所以它是co_freevars

co_freevars:自由变量名称的元组(通过函数的闭包引用

分配表达式左侧的其他变量是co_varnames

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

当您使用 global 时,您是在告诉 Python 这不是局部变量,并且当您更改它的值时,您会在 function 被定义的全局空间中更改它,而不是在它被调用的地方。

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不会在该模块的全局 scope 中找到该变量,这就是您得到: 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM