python中函数作用域

1、作用域
	如果一个变量在def内赋值,他被定位在这个函数内
	如果一个变量在一个嵌套的def中赋值,对于嵌套的函数来说,它非本地的
	如果在def之外赋值,他就是整个文件
2、在交互式模式下,其实是在一个名为__main__的模板内。
3、一个函数的内部的任何类型的赋值都会把一个名称划定为本地的。这包括=语句,import中的模板名称,def中的函数名称,函数参数名称等。如果在一个def中以任意方式赋值的名称,他都将对于该函数是本地的。
	注意:原处改变对象并不会把变量划分为本地变量。
4、变量名解析:LEGB原则
	1变量名引用分为三个作用域进行查找:首先是本地,然后是函数内(如果有的话),之后是全局的,最后是内置的
	2默认情况下,变量名赋值会创建或者改变本地变量
	3全局声明和非本地声明将赋值的变量名映射到模板文件的内部作用域。
	4当在函数中使用未认证的变量名时,python搜索4个作用域(本地作用域,之后是上一层次中的def或者lambda的本地作用域,之后是全局,最后是内置的)并且在第一处能找到这个变量的地方停下来,如果变量名在这个过程中没有找到则会报错。
5、内置作用域
	内置作用域仅仅是一个名为builtins内置模板,要在import builtins才能使用
	import builtins
	print(dir(builtins))
6、全局变量
	全局变量是位于模板文件内部的顶层的变量名
	全局变量如果在函数内部被赋值的话,必须经过声明
	全局变量在函数的内部不经过声明也可以被引用
7、工厂函数(闭合函数)
	一个能够记住嵌套作用变量的函数
	例如:
	def maker(N):
		def action(X):
			return X**N
		return action
	f = maker(2)
	print(f(2))  #输出9
8、这个例子需要思考:
	def f():
		a  = []
		for i in range(5):
			a.append(lambda x ;i**x)
		return a
	t = f()
	print(t[0](2))  #输出16
	print(t[1](2),t[2](2))  #输出16,16
	解释:因为for循环结束后,i的值是4,记住这个i=4,所以当调用时,x的值才被传进来。
	解决办法是使用默认参数:
	def f():
		a  = []
		for i in range(5):
			a.append(lambda x,i=i ;i**x)  #这里的i等于这次循环时的i
		return a
	t = f()
	print(t[0](2))  #输出0
	print(t[1](2),t[2](2))  #输出2,4
9、nonlocal使用举例
	def tester(start):
		state = start
		def nested(label):
			nonlocal state  #如果没有这个,下面的是state+=1不行的
			print(label,state)
			state+=1
		return nested

  

原文地址:https://www.cnblogs.com/hbcb533/p/3674172.html