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

松鼠的窝 2017-12-14

今天的博文翻译是关于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()

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

原文链接:love-python.blogspot.com.br/2017/06/glo…

译文链接:vimiix.com/post/2017/1…

相关推荐