Python之命名空间、闭包、装饰器

一、命名空间

  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)  #改变了值

 

以上知识点原文参考:Python命名空间的本质

 

二、闭包


什么叫闭包呢?

通俗的话将讲,就是在一个嵌套函数中,内部的函数引用了外部函数的变量,那么内部函数就是一个闭包。

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. 浅显理解 Python 闭包

2. Python闭包详解

 

三、装饰器

其实上面这个例子和装饰器,有点像,有没有?

我们把上面这个稍微改一下,变成装饰器

 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

带参数的装饰器

原文地址:http://www.imooc.com/code/6066

 

posted @ 2017-05-03 22:27  王一白  阅读(491)  评论(0编辑  收藏  举报