Python 变量作用域 LEGB (下)

上篇: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 testLocals = {'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 testLocals = {'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 2310858531600822
>>> Enclose_Func(322)yvivid's testLocals = {'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 2310858531920822

可以看到 运行两次,其中 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)>}

>>> iTraceback (most recent call last):File "<pyshell#99>", line 1, in <module>iNameError: 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

(0)

相关推荐

  • Python 为什么引入这两个关键词

    啥是 global 和 nonlocal Python 支持的关键词里,global 和 nonlocal 初学者接触的少,不知道是做什么用的:一些人虽然知道它们的作用,但对为什么要引入这两个关键词则 ...

  • 字节码:分析 Python 执行的终极利器

    一.什么是代码对象 Code Object(代码对象)封装了 Python 虚拟机的字节码和虚拟机执行相关信息,可以把字节码称为 Python 虚拟机上的汇编语言. 学代码对象有什么用呢?从其定义可知 ...

  • Python 中的函数装饰器和闭包

    函数装饰器可以被用于增强方法的某些行为,如果想自己实现装饰器,则必须了解闭包的概念. 装饰器的基本概念 装饰器是一个可调用对象,它的参数是另一个函数,称为被装饰函数.装饰器可以修改这个函数再将其返回, ...

  • 一文看懂Python系列之装饰器(decorator)(工作面试必读)

    Python的装饰器(decorator)可以说是Python的一个神器,它可以在不改变一个函数代码和调用方式的情况下给函数添加新的功能.Python的装饰器同时也是Python学习从入门到精通过程中 ...

  • python - 内置对象 之 变量

    一.变量命名规划 1.命名规则 (1)命名内容只能是字母.下划线.数字 (2)名字第1字符只能是字母或下划线 (3)区分大小写 2.私有变量 (1)_xxx "单下划线" 开始的成 ...

  • Python变量的定义以及使用

    任何编程语言都需要处理数据,比如数字.字符串.字符等,我们可以直接使用数据,也可以将数据保存到变量中,方便以后使用. 变量(Variable)可以看成一个小箱子,专门用来"盛装"程 ...

  • python变量、常量和数值类型

    人生啊... 怎么才能有滋有味... 本篇介绍python中的变量.常量和数值类型. 1.变量 Python中也有不少的数据类型,但在定义变量时,python很牛叉的地方在于,你不用管它是什么类型,p ...

  • 第3天:Python 变量与数据类型

    这篇文章我们学习 Python 变量与数据类型 一.变量 变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念,变量可以通过变量名访问.在 Python 中 变量命名规定,必须是大小写英文, ...

  • 一文介绍Python变量的三个特征

    对于每个变量,python都提供了这三个方法分别获取变量的三个特征,其中python的内置功能id(),内存地址不一样,则id()后打印的结果不一样,因为每一个变量值都有其内存地址,而id是用来反映变 ...

  • Python变量的定义和使用

    Python编程学习圈 昨天 任何编程语言都需要处理数据,比如数字.字符串.字符等,我们可以直接使用数据,也可以将数据保存到变量中,方便以后使用. 变量(Variable)可以看成一个小箱子,专门用来 ...

  • 新手教程Python变量的讲解

    Python的主要应用领域包括输入.输出.Python中的标准算术操作符等.事实上,Python的知识远不止这些,还包括循环.文件.函数.类别.模块等.我将在未来的文章中详细整理这些知识. 赋值运算符 ...

  • Python变量与数据类型的解析

    许多朋友学的很杂,很随心所欲,例如,看了基础语法之后就去看面向对象开始学习爬虫,这样学也没问题,只是你爬着爬着知道很多知识自己了解的还不完善,思维跟不上,最后不知道怎么操作,也不知道怎么写.今天为大家 ...

  • 小白必学教程:Python变量的定义和使用

    所有的一种编程语言都需要处理数据,如数字.字符串.字符等等,我们可以直接使用数据,或者把它保存到一个变量中,以方便以后使用. 变数(Variable)可看作是一个专门用于在程序中"装入&qu ...

  • Python 变量类型 | 菜鸟教程

    Python 变量类型 变量存储在内存中的值,这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据 ...