上篇: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. Spring Cloud配置中心客户端读取配置

    微服务连接配置中心来实现外部配置的读取. 引入依赖 <dependencies> <dependency> <groupId>org.springframework ...

  2. Android组件内核之Service内核原理(三)

    阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680本篇文章将先从以下三个内容来介绍Service内核原理: [startSe ...

  3. Python系列——常用第三方库

    幕布视图(更加方便.明了):https://mubu.com/doc/AqoVZ8x6m0 参考文献:嵩天老师的Python讲义 模块 定义 计算机在开发过程中,代码越写越多,也就越难以维护,所以为了 ...

  4. 【Elasticsearch 7 探索之路】(六)初识 Mapping

    上一篇主要讲解什么是 URL Search 和 Request Body Search 的语法.本篇对 Mapping 的 Dynamic Mapping 以及手动创建 Mapping 进行讲解. 1 ...

  5. go之linux安装

    下载地址:https://golang.org/dl/ ubuntu16.04安装过程 官方安装文档:https://golang.org/doc/install?download=go1.11.4. ...

  6. svnversion - 为工作代码产生一个紧缩的 (compat) 版本号

    SYNOPSIS 总览 svnversion wc_path [trail_url] OVERVIEW 概述 Subversion 是一个版本控制系统,允许保存旧版本的文件和目录 (通常是源代码),保 ...

  7. 第一章 Xshell5评估期已过问题

    您的Xshell评估期已过.请访问我们的在线商店购买Xshe许可证.产品密钥将通过电子邮件发送给您. 解决方法 一.进入下载网站 https://www.netsarang.com/zh/thank- ...

  8. vue+vue-cli2+webpack配置资源cdn

    vue-cli2+webpack构建的vue项目如何让图片和js等静态资源走cdn,哪里可以配置呢?下面我详细介绍 1.config/index.js中可以看到 module.exports = { ...

  9. String类型的时间大小比较

    不多废话,上代码   (String 的CompareTo方法比较仅仅限于同位数的字符串比较,格式.位数不一样比较结果会错误,原因是CompareTo比较源码是ASCII的比较) 代码一 packag ...

  10. nginx自动切割日志脚本

    #!/bin/bash savepath_log='/data/logs' nglogs='/data/logs' mkdir -p $savepath_log/$(date +%Y)/$(date ...