Python 使用';全球';在函数内部定义之前使用关键字?

Python 使用';全球';在函数内部定义之前使用关键字?,python,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

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

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

y=None
def foo():
全局y
打印('y在foo is'中,y)
foo()
打印('global y is',y)
foo中的y为None
全局y是零

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

例2:你明白吗

示例3:否,
bar
没有局部变量
y
。因为没有,所以它在上下文堆栈中向外搜索,并在下一个名称空间
foo
中找到
y


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

当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:自由变量名称的元组(通过 函数的闭包

位于辅助表达式左侧的其他变量是
co\u 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
时,
foo
将在该模块的全局范围内找不到该变量,这就是为什么您会得到:
NameError:未定义名称“y”

要进一步了解角色
全局
关键字,请检查以下内容:

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

Python在您的第一个代码段中没有“空变量”的概念,
global y
没有任何效果;因为在函数中没有赋值给
y
,所以它无论如何都是一个全局变量(由于缺少任何其他可能的变量).模块级的
全局y
不起任何作用。只需要函数中的一个。