作用域测试例子:

>>> 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之作用域的更多相关文章

  1. Python的作用域

    Python的作用域 转自:http://www.cnblogs.com/frydsh/archive/2012/08/12/2602100.html Python是静态作用域语言,尽管它自身是一个动 ...

  2. 详解Python的作用域和命名空间

    最近在学习Python,不得不说,Python真的是一门很好用的语言.但是学习的过程中关于变量作用域(scope)的命名空间(namespace)的问题真的把我给搞懵了.在查阅了相关资料之后,觉得自己 ...

  3. python变量作用域

    [python变量作用域] 几个概念: python能够改变变量作用域的代码段是def.class.lamda. if/elif/else.try/except/finally.for/while 并 ...

  4. Python 变量作用域 LEGB (上)—— Local,Global,Builtin

    Python 变量作用域的规则是 LEGB LEGB含义解释:L —— Local(function):函数内的名字空间E —— Enclosing function locals:外部嵌套函数的名字 ...

  5. Python 变量作用域与函数

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  6. Python 变量作用域 LEGB (下)—— Enclosing function locals

    上篇:Python 变量作用域 LEGB (上)—— Local,Global,Builtin https://www.cnblogs.com/yvivid/p/python_LEGB_1.html ...

  7. [Python] 命名空间&作用域

    Python的类语句不会创建实例 类会创建命名空间,通过对象访问类的属性和方法 类不会创建作用域,对方法和属性的引用必须加以限定(如在方法中必须通过self引用实例的属性) class My1(): ...

  8. python的作用域、globals()-全局变量 和 locals()-局部变量

    在python中,函数会创建一个自己的作用域,也称为为命名空间.当我们在函数内部访问某个变量时,函数会优先在自己的命名空间中寻找. 我们自己定义的全局变量均在python内建的globals()函数中 ...

  9. Python函数作用域的查找顺序

    函数作用域的LEGB顺序 1.什么是LEGB? L:local 函数内部作用域 E:enclosing 函数内部与内嵌函数之间 G:global 全局作用域 B:build-in 内置作用域 2.它们 ...

  10. Python 之作用域和名字空间

    作用域与名字空间 Python有一个核心概念是名字空间(namespace),namespace是一个name到object 的映射关系,Python有很多namespace,因此,在代码中如果碰到一 ...

随机推荐

  1. xml解析总结-常用需掌握

    Xml文档的解析 XML解析方式分为两种:DOM方式和SAX方式 DOM:Document Object Model, 文档对象模型.这种方式是W3C推荐的处理XML的一种方式. SAX:Simple ...

  2. MVC中Controller控制器相关技术

    第6章Controller相关技术 Controller(控制器)在ASP.NET MVC中负责控制所有客户端与服务器端的交互,并 且负责协调Model与View之间的数椐传递,是ASP.NET MV ...

  3. 在Eclipse里面使用git上传项目到码云

    Eclispe上使用git 1.安装git 按照下图的步骤: 安装过就不用再安装了,没有安装的安装一下! 安装完毕之后:需要做一些初始化的设置: 2.上传项目到码云上 1.首先在码云上建立一个项目 2 ...

  4. Opencv如何捕获摄像头视频-OpenCV步步精深

    捕获摄像头实时图像 这一点非常非常重要,因为这一点关乎了以后我们进行各种各样的识别(人脸识别,车牌识别等等有趣的识别).opencv提供了一个接口,可以轻松的让我们实现这个功能.我们先来看一段代码,根 ...

  5. 知识树杂谈Java面试(4)

    一. Java集合 1.  集合分类:  Collection.Map. 2. Collection: 3. Map 4. 注意点 a. List 有序.可重复:Set 无序.不可重复:Map  键值 ...

  6. Druid连接池

    Druid 连接池简介 Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.J ...

  7. UVa12100,Printer Queue

    水题,1A过的 数据才100,o(n^3)都能过,感觉用优先队列来做挺麻烦的,直接暴力就可以了,模拟的队列,没用stl #include <iostream> #include <c ...

  8. SQL数据库的基础操作

    一,认识SQL数据库 美国Microsoft公司推出的一种关系型数据库系统.SQLServer是一个可扩展的.高性能的.为分布式客户机/服务器计算所设计的数据库管理系统,实现了与WindowsNT的有 ...

  9. Vector容器构造函数

    No1 vector(); No2 vector( const vector& c ); No3 explicit vector( size_type num, const TYPE& ...

  10. Nginx-OpenResty安装配置

    上两篇中介绍了: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 Ngnix技术研究系列2-基于Redis实现动态路由 发现,应该加一篇OpenResty的安装部署说明,方便大家按图索骥 ...