• 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()# 外部无法调用内部的函数,这个使用直接报错
  • 相关阅读:
    hihoCoder #1078 : 线段树的区间修改
    hihoCode r#1077 : RMQ问题再临-线段树
    hihoCoder #1070 : RMQ问题再临
    hihoCoder #1068 : RMQ-ST算法(模板)
    LeetCode Valid Sudoku 有效数独
    150 Evaluate Reverse Polish Notation 逆波兰表达式求值
    149 Max Points on a Line 直线上最多的点数
    148 Sort List 链表上的归并排序和快速排序
    147 Insertion Sort List 链表插入排序
    146 LRU Cache 最近最少使用页面置换算法
  • 原文地址:https://www.cnblogs.com/jianchixuexu/p/12708449.html
Copyright © 2020-2023  润新知