上篇: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. ACM 中的对拍程序

    所谓对拍,就是随机生成数据,然后用一个肯定正确的暴力算法的程序,去测试一个要提交的程序. 由于比赛中一般使用 Linux 系统,所以本篇博客的代码都是 Linux 下的程序代码. 其实最简单的方式是写 ...

  2. PHP 图片裁切

    PHP CLASS TO CREATE IMAGE THUMBANILS Some years ago, I wrote a PHP class to create image thumbnails ...

  3. Linux下的解压缩

    Linux下常见的压缩包格式有5种:zip tar.gz tar.bz2 tar.xz tar.Z 其中tar是种打包格式,gz和bz2等后缀才是指代压缩方式:gzip和bzip2 filename. ...

  4. leetcode.双指针.633平方数之和-Java

    1. 具体题目 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a^2 + b^2 = c. 示例1: 输入: 5 输出: True 解释: 1 * 1 + 2 * 2 = 5 注 ...

  5. 集中式日志系统 ELK 协议栈详解

    简介 在我们日常生活中,我们经常需要回顾以前发生的一些事情:或者,当出现了一些问题的时候,可以从某些地方去查找原因,寻找发生问题的痕迹.无可避免需要用到文字的.图像的等等不同形式的记录.用计算机的术语 ...

  6. Python-数字类型补充

    Python第五节数字类型补充 数字类型转换 int(x) float(x) complex(x) complex(x, y) 数学常量 pi e PS 数字类型不允许改变 也就是说,当我们对数字类型 ...

  7. ubuntu14.04 配置android studio环境

    二.复制所需的文件到ubuntu 2.1.如果你还没有linux版本的android studio.sdk.jdk请先下载所需文件,我已经上传到百度网盘了 下载地址: android studio-l ...

  8. dubbo-源码阅读之服务发布

    原理 dubbo根据spring 2.0的schma实现 解析xml并初始化相关bean 初始化dubbo:service为ServiceBean实例  通过spring的生命周期相应回调实现服务发布 ...

  9. master挂了的话pm2怎么处理 使用pm2方便开启node集群模式

    本文为转载 Introduction As you would probably know, Node.js is a platform built on Chrome's JavaScript ru ...

  10. 【leetcode】958. Check Completeness of a Binary Tree

    题目如下: Given a binary tree, determine if it is a complete binary tree. Definition of a complete binar ...