zoukankan      html  css  js  c++  java
  • 2020年3月15日python学习笔记——名称空间和闭包

    # 名称空间:正是存放名字x与1绑定关系的地方(x = 1)
    # 定义:又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?
    # 名称空间正是存放名字x与1绑定关系的地方

    # 备注:python里面有很多名字空间,每个地方都有自己的名字空间,互不干扰,不同空间中的两个相同名字的变量之间没有任何联系。

    # 名称空间有4种: LEGB
    # L:locals:函数内部的名字空间,一般包括函数的局部变量以及形式参数
    # E:enclosing function:在嵌套函数中外部函数的名字空间, 若fun2嵌套在fun1里,对fun2来说, fun1的名字空间就是enclosing.
    # G:globals:当前的模块空间,模块就是一些py文件。也就是说,globals()类似全局变量。
    # B:builtins: 内置模块空间,也就是内置变量或者内置函数的名字空间,print(dir(__builtins__))可查看包含的值。
    # print(dir(__builtins__))
    # __builtins__使用场景:模块的里面的使用

    #备注: 不同变量的作用域不同就是由这个变量所在的名称空间决定的。

    # 作用域即范围:经常使用的2种
    # 全局范围:全局存活,全局有效
    # 局部范围:临时存活,局部有效

    # 查看作用域方法 globals(),locals()

    # 作用域查找顺序
    # 当程序引用某个变量的名字时,就会从当前名字空间开始搜索。搜索顺序规则便是: LEGB。即locals -> enclosing function -> globals -> builtins。
    # 一层一层的查找,找到了之后,便停止搜索,如果最后没有找到,则抛出在NameError的异常。
    # 例如:
    # level = 'L0'
    # n = 22
    # def func():
    # level = 'L1'
    # n = 33
    # print(locals()) # {'level': 'L1', 'n': 33}
    # def outer():
    # n = 44
    # level = 'L2'
    # print("outer:",locals(),n) #outer: {'level': 'L2', 'n': 44} 44
    # def inner():
    # level = 'L3'
    # print("inner:",locals(),n) #此出打印的n是多少? inner: {'level': 'L3', 'n': 44} 44
    # inner()
    # outer()
    # func()


    # 备注:就是逐层向上查找,查找最近的值



    # 闭包是个什么东西?
    # 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。
    # 当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
    # 也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。
    # 这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。

    # def outer():
    # name = '小武哥'
    # def inner():
    # print("在inner里打印外层函数的变量",name)
    # return inner # 注意这里只是返回inner的内存地址,并未执行
    # f = outer()
    # print(f) #inner at 0x01A8E810>
    # f() # 相当于执行的是inner()

    # # 以上程序解释了闭包:
    # 1、有函数嵌套
    # 2、内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数
    # 3、跨一级可以仍然可以调用里面的内容,也就是,在最外层直接调用inner按道理不可以,但是进过return可以实现
    # 4、嵌套函数里面需要有关键字return

    # 以上代码执行原理:从outer进行运行开始,进入后见到return结束,返回嵌套函数inner的地址,直接inner加()直接运行嵌套里面的函数了
    # 注意此时outer已经执行完毕,正常情况下outer里的内存都已经释放了,但此时由于闭包的存在,我们却还可以调用inner,
    # 并且inner内部还调用了上一层outer里的name变量。这种粘粘糊糊的现象就是闭包。

    # 闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

    # 备注:闭包在哪会用? 装饰器就此产生了


    # 函数嵌套:问题是 inner()在外部直接无法调用了,闭包搞定这个事情
    # 1、有函数嵌套
    # 2、内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数
    # def outer():
    # name = '小武哥'
    # def inner():
    # print("在inner里打印外层函数的变量",name)
    # inner()
    # outer()
    # inner()# 外部无法调用内部的函数,这个使用直接报错
  • 相关阅读:
    WCF 第四章 绑定 在多个绑定上暴露一个服务契约
    WCF 第五章 行为 事务跨操作事务流
    WCF 第五章 导出并发布元数据(服务行为)
    WCF 第五章 行为 通过配置文件暴露一个服务行为
    WCF 第五章 不支持会话的绑定的默认并发和实例
    WCF 第五章 并发和实例(服务行为)
    WCF 第五章 行为 总结
    WCF 第四章 绑定 绑定元素
    WCF 第五章 行为 事务之选择一个事务协议OleTx 或者WSAT
    WCF 第四章 绑定 比较各种绑定的性能和可扩展性
  • 原文地址:https://www.cnblogs.com/jianchixuexu/p/12708449.html
Copyright © 2011-2022 走看看