Python 变量作用域 LEGB (下)—— Enclosing function locals
上篇: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的更多相关文章
- Python 变量作用域 LEGB (上)—— Local,Global,Builtin
Python 变量作用域的规则是 LEGB LEGB含义解释:L —— Local(function):函数内的名字空间E —— Enclosing function locals:外部嵌套函数的名字 ...
- Python 变量作用域与函数
Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...
- python变量作用域
[python变量作用域] 几个概念: python能够改变变量作用域的代码段是def.class.lamda. if/elif/else.try/except/finally.for/while 并 ...
- Python基本语法_变量作用域LEGB
目录 目录 软件系统 变量的作用域 高级语言对数据类型的使用过程 作用域的产生 作用域的类型 Llocal局部作用域 Eenclosing嵌套作用域 Gglobal全局作用域 Bbuilt-in内置作 ...
- python函数作用域LEGB
我们的在学习Python函数的时候,经常会遇到很多定义域的问题,全部变量,内部变量,内部嵌入的函数,等等,Python是如何查找的呢?以及Python又是按照什么顺序来查找的呢?这里做一个顺序的说明 ...
- python——变量作用域及嵌套作用域
----------------------------------------------------------------------------- 前言-------------------- ...
- python 变量作用域、闭包
先看一个问题: 下面代码输出的结果是0,换句话说,这个fucn2虽然已经用global声明了variable1,但还是没有改变变量的值 def func1(): variable1=0 def fun ...
- python的作用域、globals()-全局变量 和 locals()-局部变量
在python中,函数会创建一个自己的作用域,也称为为命名空间.当我们在函数内部访问某个变量时,函数会优先在自己的命名空间中寻找. 我们自己定义的全局变量均在python内建的globals()函数中 ...
- python变量作用域,函数与传参
一.元组传值: 一般情况下函数传递参数是1对1,这里x,y是2个参数,按道理要传2个参数,如果直接传递元祖,其实是传递一个参数 >>> def show( x, y ): ... p ...
随机推荐
- python作业/练习/实战:生成双色球小程序
作业要求: 每注投注号码由6个红色球号码和1个蓝色球号码组成.红色球号码从1--33中选择:蓝色球号码从1--16中选择 代码范例 import random all_red_ball = [str( ...
- PAT甲级——A1143 LowestCommonAncestor【30】
The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has both U ...
- 力扣算法——136SingleNumber【E】
Given a non-empty array of integers, every element appears twice except for one. Find that single on ...
- My Sublime
Package Control:插件包管理工具 Soda:一个流行的主题,包含代码着色.标签.图标 Emmet:流行的Html编写插件,是zed code升级版包含css编写 SublimeLinte ...
- linux 下安装chrome的rpm包
1. 下载chrome的rpm包,假设叫cho. 2.执行命令 rpm -ivh cho 3.报错提示需要lsb>=4.0,执行命令 yum install lsb 等待安装完毕. 4. 重新执 ...
- c# PID算法入门
离开工控行业已经有一段时间了,最近回忆起以前的工作,又对 PID 算法有了兴趣.所以写了一个小项目,希望可以帮到需要的人,也算是对那段工作经历的一个总结. 这是一个 winform 的项目.负载是一个 ...
- cordova-plugin-alipay-v2使用篇(更新至20170725)(亲测可用)
cordova-plugin-alipay-v2使用篇(更新至20170725)(亲测可用) alipaySdk已更新至20170725版本 支付宝WS_APP_PAY_SDK_BASE_2.0 &l ...
- Android开发:图文分析 Handler通信机制 的工作原理
前言 在Android开发的多线程应用场景中,Handler机制十分常用 下面,将图文详解 Handler机制 的工作原理 目录 1. 定义 一套 Android 消息传递机制 2. 作用 在多线程的 ...
- 通过list中值得名称查询索引号
>>> a = ['www','iplaypython','com']>>> a.index('iplaypython')
- 【Luogu】【关卡2-11】简单数学问题(2017年10月)【还差三道题】
火星人 麦森数 P1403 [AHOI2005]约数研究 f(n)表示n的约数个数,现在给出n,要求求出f(1)到f(n)的总和. 解答:有几个1做约数的个数 = n /1; 有几个2做约数的个数 = ...