zoukankan      html  css  js  c++  java
  • 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:Python27libcopy.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

  • 相关阅读:
    小程序本地数据的存储
    cocos2d-x中CCTableView介绍
    C++中map容器的说明和使用技巧
    不修改代码,关闭vs2010 C4819警告
    Cocos2d-x 处理双击事件的两种方法
    Cocos2d-x 实现模态对话框
    Cocos2d-x init() 和 onEnter() 区别
    Cocos2d-x 中 CCProgressTimer
    Cocos2d-x 实现技能冷却效果
    输出第 n 个斐波纳契数(Fibonacci)
  • 原文地址:https://www.cnblogs.com/wongbingming/p/6804353.html
Copyright © 2011-2022 走看看