一、命名空间
1. 命名空间
命名空间是一个字典,key是变量名(包括函数、模块、变量等),value是变量的值。
2. 命名空间的种类和查找顺序
- 局部命名空间:当前函数
- 全局命名空间:当前模块
- 内建命名空间:所有Python环境,所有模块
查找顺序
1、先在当前 (嵌套的或 lambda) 函数的命名空间中搜索
2、然后是在父函数的命名空间中搜索
3、接着是模块命名空间中搜索
4、最后在内置命名空间中搜索
NameError
这里看一个例子
i = 1
def func():
i += 1
func()
#错误:UnboundLocalError: local variable 'i' referenced before assignment
由于,func函数在创建的时候,i有赋值操作,所以就在局部命名空间生成一个i的变量但是并没有实际值,而在全局命名空间中同样也会生成i这个变量,齐值为1;
在运行的时候,由于先检索的是局部命名空间有i,所以就终止检索,但是由于没有具体值,所以返回错误。
3. 命名空间的访问
局部命名空间通过locals() 访问
globals()
举个例子
'''Created on 2017-5-3'''
import copy
from copy import deepcopy
gstr = "global string"
def func1(i, info):
x = 12345
print(locals())
func1(1 , "first")
if __name__ == "__main__":
print("the current scope's global variables:")
dictionary=globals()
print(dictionary)
运行结果
{'info': 'first', 'x': 12345, 'i': 1} #局部命名空间locals()
the current scope's global variables: #全局命名空间globals()
{'func1': <function func1 at 0x0000000002BB3978>,
'gstr': 'global string',
'dictionary': {...},
'__builtins__': <module '__builtin__' (built-in)>,
'__file__': 'C:\\Users\\Administrator\\PycharmProjects\\Sample\\test.py',
'__package__': None,
'deepcopy': <function deepcopy at 0x0000000002BB3518>,
'__name__': '__main__',
'copy': <module 'copy' from 'C:\Python27\lib\copy.pyc'>,
'__doc__': 'Created on 2017-5-3'
}
4. locals与globals的一点区别
locals 是只读的,globals 不是
示例
def func1(i, info):
x = 666
print(locals())
locals()["x"]= 888
print("x=",x)
y=333
func1(1 , "first")
globals()["y"]=777
print( "y=",y)
输出
{'info': 'first', 'x': 666, 'i': 1}
('x=', 666) #并没有改变
('y=', 777) #改变了值
二、闭包
什么叫闭包呢?
通俗的话将讲,就是在一个嵌套函数中,内部的函数引用了外部函数的变量,那么内部函数就是一个闭包。
1 def outer_func(num1):
2 def inner_func(num2):
3 return num1*num2
4 return inner_func
5
6 func = outer_func(2)
7 print func(3)
运行结果为:6
inner_func() 就是一个闭包,因为他 引用了外部函数的变量num1
三、装饰器
其实上面这个例子和装饰器,有点像,有没有?
我们把上面这个稍微改一下,变成装饰器
1 def outer_func(func):
2 def new(num2):
3 func(num2)
4 return new
5
6 num1=2
7 @outer_func
8 def inner_func(num2):
9 print num1*num2
10
11 inner_func(3)
运行结果:6
带参数的装饰器