上篇:Python 变量作用域 LEGB (上)—— Local,Global,Builtin

https://www.cnblogs.com/yvivid/p/python_LEGB_1.html

下篇 没想到 拖这么久,距离上篇完成 都一年多了。

一、闭包常规形态下的 locals作用域

 典型的闭包 如下:

def outer(x = 3):
def inner(y):
print("yvivid's test")
print("Locals =", locals())
print("Globals =", globals())
return x+y
return inner

运行结果如下:

>>> Enclose_Func = outer(73)
>>> Enclose_Func(10)
yvivid's test
Locals = {'y': 10, 'x': 73}
Globals = {'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
'outer': <function outer at 0x0000018AFDB0CD90>,
'Enclose_Func': <function outer.<locals>.inner at 0x0000018AFB091EA0>}
83

可以看到,在 闭包内查看 locals() 时,可以看到 x 和 y。

为了进一步看,x 和 y 是否变化,yvivid将代码变更为如下:

def outer(x = 3):
def inner(y):
print("yvivid's test")
print("Locals =", locals())
print("Globals =", globals())
print(id(x), id(y))
return x + y
return inner

即,仅增加了 id 的判定。考虑到 python 数字引用机制,使用大于255的数字进行测试。

运行结果如下:

>>> Enclose_Func = outer(500)
>>> Enclose_Func(322)
yvivid's test
Locals = {'y': 322, 'x': 500}
Globals = {'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,

'__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
'outer': <function outer at 0x0000021A09E8CD90>,
'Enclose_Func': <function outer.<locals>.inner at 0x0000021A09E86158>}
2310858531312 2310858531600

822
>>> Enclose_Func(322)
yvivid's test
Locals = {'y': 322, 'x': 500}
Globals = {'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
'outer': <function outer at 0x0000021A09E8CD90>,
'Enclose_Func': <function outer.<locals>.inner at 0x0000021A09E86158>}
2310858531312 2310858531920
822

可以看到 运行两次,其中 id(y) 是不变更的,而 id(x) 发生了变更,因此 每次 x 是作为形参传入的。而 y 是在 Enclose_Func = outer(500) 时 确定的。

二、闭包特殊形态下的 locals作用域

在 Python 中 部分特殊的 闭包形式。

1、列表推导

>>> [ 'Locals =' + repr(locals()) for i in range(4)]
["Locals ={'i': 0, '.0': <range_iterator object at 0x000002C2563CE330>}",
"Locals ={'i': 1, '.0': <range_iterator object at 0x000002C2563CE330>}",
"Locals ={'i': 2, '.0': <range_iterator object at 0x000002C2563CE330>}",
"Locals ={'i': 3, '.0': <range_iterator object at 0x000002C2563CE330>}"] >>> print("Globals =", globals())
'Globals =', {'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None, '__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>}
>>> i
Traceback (most recent call last):
File "<pyshell#99>", line 1, in <module>
i
NameError: name 'i' is not defined

可以看到 在yvivid做的 列表推导测试中,globals() 中 是看不到 列表推导中 变量 i 的。

这个和 for 循环有很大的不同。

2、生成器

yvivid_generator = ('Locals =' + repr(locals()) for i in range(4))

3、集合推导

yvivid_set = {'Locals =' + repr(locals()) for i in range(4)}

-------

A、代码 都基于 Python 3.6 环境。

B、参考书籍 《Python学习手册(第四版)》

【原创文档,引用请声明出处,yvivid】https://www.cnblogs.com/yvivid/p/python_LEGB_2.html

Python 变量作用域 LEGB (下)—— Enclosing function locals的更多相关文章

  1. Python 变量作用域 LEGB (上)—— Local,Global,Builtin

    Python 变量作用域的规则是 LEGB LEGB含义解释:L —— Local(function):函数内的名字空间E —— Enclosing function locals:外部嵌套函数的名字 ...

  2. Python 变量作用域与函数

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  3. python变量作用域

    [python变量作用域] 几个概念: python能够改变变量作用域的代码段是def.class.lamda. if/elif/else.try/except/finally.for/while 并 ...

  4. Python基本语法_变量作用域LEGB

    目录 目录 软件系统 变量的作用域 高级语言对数据类型的使用过程 作用域的产生 作用域的类型 Llocal局部作用域 Eenclosing嵌套作用域 Gglobal全局作用域 Bbuilt-in内置作 ...

  5. python函数作用域LEGB

    我们的在学习Python函数的时候,经常会遇到很多定义域的问题,全部变量,内部变量,内部嵌入的函数,等等,Python是如何查找的呢?以及Python又是按照什么顺序来查找的呢?这里做一个顺序的说明 ...

  6. python——变量作用域及嵌套作用域

    ----------------------------------------------------------------------------- 前言-------------------- ...

  7. python 变量作用域、闭包

    先看一个问题: 下面代码输出的结果是0,换句话说,这个fucn2虽然已经用global声明了variable1,但还是没有改变变量的值 def func1(): variable1=0 def fun ...

  8. python的作用域、globals()-全局变量 和 locals()-局部变量

    在python中,函数会创建一个自己的作用域,也称为为命名空间.当我们在函数内部访问某个变量时,函数会优先在自己的命名空间中寻找. 我们自己定义的全局变量均在python内建的globals()函数中 ...

  9. python变量作用域,函数与传参

    一.元组传值: 一般情况下函数传递参数是1对1,这里x,y是2个参数,按道理要传2个参数,如果直接传递元祖,其实是传递一个参数 >>> def show( x, y ): ... p ...

随机推荐

  1. Codeforces Round #499 (Div. 2) Problem-A-Stages(水题纠错)

    CF链接  http://codeforces.com/contest/1011/problem/A Natasha is going to fly to Mars. She needs to bui ...

  2. 11.Jmeter 快速入门教程 -- jmeter事务控制器

    你肯定知道, jmeter是一个跨系统平台的性能测试工具, 比如他可以在linux,freebsd,windows,solaris 等等各种系统上可以运行. 我可以说, 事务 transaction ...

  3. Django Paginator分页器

    如何实现在django中实现分页效果,我使用的是django自带的分页器paginator具体是使用办法是这样的首先引用from django.core.paginator import Pagina ...

  4. Java-技术专区-虚拟机系列-内存模型(JMM)

           Java8内存模型—永久代(PermGen)和元空间(Metaspace) 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部 ...

  5. windows xp .net framework 4.0 HttpWebRequest 报The underlying connection was closed,基础连接已关闭

    windows xp .net framework 4.0 HttpWebRequest 报The underlying connection was closed,基础连接已关闭,错误的解决方法 在 ...

  6. JNI Hello World

    1.什么是JNI:               JNI(Java Native Interface):java本地开发接口               JNI是一个协议,这个协议用来沟通java代码和 ...

  7. LinkedBlockingQueue 学习

    LinkedBlockingQueue 链表队列,其元素构成为: static class Node<E> { E item; Node<E> next; Node(E x) ...

  8. Opencv 特征提取与检测-Haar特征

    Haar特征介绍(Haar Like Features) 高类间变异性 低类内变异性 局部强度差 不同尺度 计算效率高 这些所谓的特征不就是一堆堆带条纹的矩形么,到底是干什么用的?我这样给出 ...

  9. Async Clipboard AP

    转自奇舞周刊,个人学习记录,侵权删 编者按:本文作者李松峰,资深技术图书译者,翻译出版过40余部技术及交互设计专著,现任360奇舞团高级前端开发工程师,360前端技术委员会委员.W3C AC代表 如果 ...

  10. Kali Linux更新和配置

    1.用vim打开 /etc/apt/source.list root@kali:~# vim /etc/apt/sources.list #中科大 deb http://mirrors.ustc.ed ...