[译]python中的global和nonlocal的实践

今天的博文翻译是关于python中global和nonlocal两个关键字的用法,原文的作者是来自孟加拉国的Tamim Shahriar,他的博客非常适合新手朋友去阅读,都是简短而有意义的python实践。

我们大多数人都对Python中的全局变量很熟悉了。如果我们在一个模块中声明全局变量,模块内部的任何函数都可以访问这个全局变量。(模块可以理解为一个python文件或.py文件)

例如下面的代码:

x = 5

def myfnc():
    print("inside myfnc", x)
    def myfnc2():
        print("inside myfnc2", x)
    myfnc2()

myfnc()

这段代码将会输出:

inside myfnc 5
inside myfnc2 5

如果我们来改变一下代码,就像下面这样:

x = 5

def myfnc():
    print("inside myfnc", x)
    def myfnc2():
        print("inside myfnc2", x)
        x = 10
        print("x = ", x)

    myfnc2()

myfnc()

结果会得到如下错误:

File "program.py", line 6, in myfnc2
    print("inside myfnc2", x)
UnboundLocalError: local variable 'x' referenced before assignment

在函数myfnc2()中一旦声明了x = 10,Python就会认为x是一个局部变量(译者注:此处涉及到python的BGEL变量优先级原则,可参考此文章了解),而在打印函数时,x在声明之前就使用了它,所有它给出了这个错误。因为局部变量是在编译时才确定的(来自官方文档:“事实上,局部变量已经是静态确定了”)(译者注:对于这句话没法直观的理解,可以继续参考这篇翻译)如果将x声明是全局的,则可以排除这个错误。

x = 5

def myfnc():
    print("inside myfnc", x)
    def myfnc2():
        global x
        print("inside myfnc2", x)
        x = 10
        print("x = ", x)

    myfnc2()

myfnc()

现在你可以再次运行程序,它就不会抛出任何错误。

如果我们现在这样写呢?

x = 5

def myfnc():
    print("inside myfnc", x)
    y = 10
    def myfnc2():
        global x
        print("inside myfnc2", x, y)
        x = 10
        print("x = ", x)

    myfnc2()

myfnc()

如果你运行该程序,你会看到正确的输出。但是如果要在myfnc2()中写入y(例如,指定y = 1之类),则不能使用 global y,因为y不是全局变量。你不妨试试下面这个失败的代码:

x = 5

def myfnc():
    print("inside myfnc", x)
    y = 10
    def myfnc2():
        global x
        global y
        print("inside myfnc2", x, y)
        x = 10
        print("x = ", x)
        y = 1
        print("y = ", y)

    myfnc2()

myfnc()

你会得到这个错误:NameError: name 'y' is not defined

我们需要明白,y不是一个全局变量。这里nonlocal就起作用了!仅仅只需写成nonlocal y来替换global y。它就可以使myfnc2()中的y正常读写,调用。

x = 5

def myfnc():
    print("inside myfnc", x)
    y = 10
    def myfnc2():
        global x
        nonlocal y
        print("inside myfnc2", x, y)
        x = 10
        print("x = ", x)
        y = 1
        print("y = ", y)

    myfnc2()

myfnc()

这是我今天学到的东西。 :)

原文链接:http://love-python.blogspot.com.br/2017/06/global-and-nonlocal-variable-in-python.html?view=classic

译文链接:http://vimiix.com/post/2017/12/14/global-and-nonlocal-variable-in-Python/

Discuss

Scroll to top