变量的定义
先了解一下python中对于变量的定义:全局变量,局部变量,自由变量。
If a name is bound in a block, it is a local variable of that block, unless declared as nonlocal. If a name is bound at the module level, it is a global variable. (The variables of the module code block are local and global.) If a variable is used in a code block but not defined there, it is a free variable.
翻译过来就是:如果一个名称被绑定在一个块中,那么它就是该块的一个局部变量,除非声明为非局部变量。如果名称在模块级绑定,则它是一个全局变量。(模块代码块的变量是局部变量和全局变量。)如果一个变量在一个代码块中使用,但没有在那里定义,那么它就是一个自由变量。
可能每个人对于这段话的理解有些自己的见解。在这儿我是把自由变量更多的是称之为绑定自由变量(闭包内会进行绑定)
什么闭包?
1、函数内部定义另一个函数。
2、外函数返回内函数的引用。
3、内函数调用外函数的变量。
闭包的范围
从外函数定义完毕的位置到返回值前,中间的所有代码块(包括外函数的局部变量、内函数的代码块)才是一个闭包的范围,并不是从开始定义外函数到外函数完全返回的所有代码块,只有中间的一部分才真正算是一个闭包的范围。
def fun1():
temp = [ ]
def fun2(*args, **kwargs):
temp.append((args, kwargs))
return temp
return fun2
这就是一个简单的闭包。当我们调用fun1()时,返回的是什么?
返回的是fun2的引用。我们可以赋值给一个变量,a = fun1()。在以后的使用中直接a()就可以调用内函数fun2。而这个时候temp就是一个只属于fun2的绑定自由变量。我自己也喜欢称为伪全局变量。
我们通过打印a的局部变量和自由变量可以得到:('args', 'kwargs')和('temp',)。只要程序(项目)没有停止,在任何地方调用a(*args, **kwargs)都可以随时为temp里面添加元素。这里我们也是利用列表的可变性,如果temp是不可变类型,那我们就需要利用nonlocal在内函数内对temp进行非局部声明,如果对temp进行新的赋值,那么fun2绑定的自由变量也会跟着更新。
边想边写,比较碎。有不同见解的可以留言,我看到了一定及时回复。下次再有时间,准备写下装饰器和利用装饰器实现单例。