Python之作用域
作用域测试例子:
>>> a = 10
>>> def test():
... a = 20
... print a
...
>>> a
10
>>> test()
20
>>> a #执行test之后,a的值还是10,没有变
10
这里涉及作用域问题。
作用域
函数形参和内部变量都存储在locals名字空间中。
>>> def test(a,*args,**kwargs):
... s = "Hello test!"
... print locals()
...
>>> test(1,"a","b",x=10,y="hi")
{'a': 1, 's': 'Hello test!', 'args': ('a', 'b'), 'kwargs': {'y': 'hi', 'x': 10}}
除非使用global、nolocal特别声明,否则在函数内部使用赋值语句,总是在locals名字空间中新建一个对象关联。注意:赋值是指名字指向新的对象,而非通过名字改变对象状态。
回过头来看看上面的例子:
>>> a = 10
>>> def test():
... a = 20
... print a
...
>>> a
10
>>> test() #两个x指向不同的对象
20
>>> a #外部变量没有被修改
10
如果仅仅是引用外部变量,那么按LEGB顺序在不同作用域查找该名字。
名字查找顺序:
locals ->enclosing function ->global ->__builtins__
>>> a = 10
>>> locals()
{'a': 10, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff578>, '__name__': '__main__', '__doc__': None}
>>>
>>> def test():
... a = 20
... print locals()
... print globals()
...
>>> globals() #和locals相同
{'a': 10, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff5f0>, '__name__': '__main__', '__doc__': None}
>>> test()
{'a': 20} #locals只有形参
{'a': 10, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff5f0>, '__name__': '__main__', '__doc__': None}
*locals:函数内部名字空间,包括局部变量和形参
*enclosing function:外部嵌套函数的名字空间
*globals:函数定义所在模块的名字空间
*__builtins__:内置模块的名字空间
如果想将外部名字关联到一个新对象,就需要使用global关键字,指明要修改的是globals空间。
>>> a = 10
>>> def test():
... global a #声明a,b是globals名字空间中的
... global b
... a = 20
... b = 30
... print "a in test= ",a
... print "b in test=",b
...
>>> globals()
{'a': 10, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff2a8>, '__name__': '__main__', '__doc__': None}
>>> test()
a in test= 20
b in test= 30
>>> globals()
{'a': 20, 'b': 30, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x7f1ce69ff2a8>, '__name__': '__main__', '__doc__': None}
>>> if True:
... a = 10
...
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'a': 10, '__package__': None}
>>> if False:
... b = 10
...
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'a': 10, '__package__': None}
>>> def test():
...
KeyboardInterrupt
>>> b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
因为b变量对应的分支是False,不会产生b变量,而a不同,a已经在globals存在,故使用a没有问题,而使用b会出现错误。
Python之作用域的更多相关文章
- Python的作用域
Python的作用域 转自:http://www.cnblogs.com/frydsh/archive/2012/08/12/2602100.html Python是静态作用域语言,尽管它自身是一个动 ...
- 详解Python的作用域和命名空间
最近在学习Python,不得不说,Python真的是一门很好用的语言.但是学习的过程中关于变量作用域(scope)的命名空间(namespace)的问题真的把我给搞懵了.在查阅了相关资料之后,觉得自己 ...
- python变量作用域
[python变量作用域] 几个概念: python能够改变变量作用域的代码段是def.class.lamda. if/elif/else.try/except/finally.for/while 并 ...
- Python 变量作用域 LEGB (上)—— Local,Global,Builtin
Python 变量作用域的规则是 LEGB LEGB含义解释:L —— Local(function):函数内的名字空间E —— Enclosing function locals:外部嵌套函数的名字 ...
- Python 变量作用域与函数
Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...
- Python 变量作用域 LEGB (下)—— Enclosing function locals
上篇:Python 变量作用域 LEGB (上)—— Local,Global,Builtin https://www.cnblogs.com/yvivid/p/python_LEGB_1.html ...
- [Python] 命名空间&作用域
Python的类语句不会创建实例 类会创建命名空间,通过对象访问类的属性和方法 类不会创建作用域,对方法和属性的引用必须加以限定(如在方法中必须通过self引用实例的属性) class My1(): ...
- python的作用域、globals()-全局变量 和 locals()-局部变量
在python中,函数会创建一个自己的作用域,也称为为命名空间.当我们在函数内部访问某个变量时,函数会优先在自己的命名空间中寻找. 我们自己定义的全局变量均在python内建的globals()函数中 ...
- Python函数作用域的查找顺序
函数作用域的LEGB顺序 1.什么是LEGB? L:local 函数内部作用域 E:enclosing 函数内部与内嵌函数之间 G:global 全局作用域 B:build-in 内置作用域 2.它们 ...
- Python 之作用域和名字空间
作用域与名字空间 Python有一个核心概念是名字空间(namespace),namespace是一个name到object 的映射关系,Python有很多namespace,因此,在代码中如果碰到一 ...
随机推荐
- IBatis.Net 老技术新研究
我们现在用的数据访问组件封装了IBatis.Net框架,提供了标准的数据访问接口和服务.正好总结一下老技术IBatis.Net在进行实际的数据访问开发之前,我们先了解一下:IBatis.Net中几个重 ...
- 易语言关于使用CURL,网页_访问,网页_访问S,网页_访问_对象,鱼刺(winHttpW)发送Get性能测试
易语言关于使用 CURL,网页_访问,网页_访问S,网页_访问_对象,鱼刺(winHttpW)发送Get性能测试 测试模块情况: |-精易模块5.8 |-鱼刺类Http |-libCURL +++ ...
- angular实现输入框输入添加 搜索框查询
!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&g ...
- JAVA基础-反射
一.反射的介绍 JAVA反射机制是在运行状态中,能够获取任意一个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法.这种动态获取的以及动态调用对象的方法的功能称为java语言的反射机制. ...
- masonry 设置控件抗压缩及抗拉伸
使用masonry正常设置约束时两个label的显示是下图 添加代码设置蓝色label的抗压缩属性后( [self.missionNameLabel setContentCompressionResi ...
- string使用
一.list和string转化 List转字符串,用逗号隔开 List<string> list = new List<string>();list.Add("a&q ...
- 张高兴的 Windows 10 IoT 开发笔记:HC-SR04 超声波测距模块
HC-SR04 采用 IO 触发测距.下面介绍一下其在 Windows 10 IoT Core 环境下的用法. 项目运行在 Raspberry Pi 2/3 上,使用 C# 进行编码. 1. 准备 H ...
- Docker中搭建zookeeper集群
1.获取官方镜像 从dockerhub获取官方的zookeeper镜像: docker pull zookeeper 2.了解镜像内容 拉取完镜像后,通过 docker inspect zookeep ...
- Bootstrap--下拉菜单.dropdown
下拉菜单.dropdown .dropdown <下拉菜单触发器button+下拉菜单ul> .dropdown 包裹层 .dropdown-toggle 下拉菜单触发器 data-to ...
- OOAD-设计模式(三)之创建型设计模式(5种)
前言 前面介绍了OOAD的基础知识,现在我们来详细的说明一下GOF设计模式中的23种模式,希望大家能够学到东西! 一.工厂方法模式(Factory Method) 1.1.工厂方法模式概述 工厂方法模 ...