在Python中,对象是独立的,不同作用域中的不同名字都可以被绑定在同一个对象上,当然对这个对象的修改会影响所有的引用。赋值操作就是名字和对象的绑定或重绑定。这和C++中的引用是一样的。

1,基础概念

1.1 命名空间(namespace)

namespace is a mapping from names to objects

命名空间是名字和对象的映射。也就是可以把一个namespace理解为一个字典,实际上很多当前的Python实现namespace就是用的字典。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。

那么哪些可以是一个namespace呢,比如Python的built-in names(包括内置函数,内置常量,内置类型);一个模块的global names(这个模块定义的函数,类,变量);一个函数的所有local names;还有一个类对象的所有属性(数据成员,成员函数)都组成一个命名空间。

命名空间都是有创建时间和生存期的。对于Python built-in names组成的命名空间,它在Python解释器启动的时候被创建,在解释器退出的时候才被删除;对于一个Python模块的global namespace,它在这个module被import的时候创建,在解释器退出的时候退出;对于一个函数的local namespace,它在函数每次被调用的时候创建,函数返回的时候被删除。

[总结]一个模块的引入,函数的调用,类的定义都会引入命名空间,函数中的再定义函数,类中的成员函数定义会在局部namespace中再次引入局部namespace。

1.2 作用域(scope)

scope is a textual region of a Python program where a namespace is directly accessible.

作用域是Python程序(文本)的某一段或某些段,在这些地方,某个命名空间中的名字可以被直接引用。这个作用域就是这个命名空间的作用域。

一个Python程序的几个作用域:

  1. 最里面的局部作用域
  2. 外层函数的局部作用域
  3. 模块的全局作用域
  4. 包含Python内置对象的最外层作用域

关于作用域,参加Python基础-函数这片博客中2小节的例子。

1.3 赋值(assignment)

Assignments do not copy data — they just bind names to objects.

赋值操作不会拷贝,只是把名字和对象做一个绑定。也就是赋值语句是起一个绑定或重绑定的作用(bind or rebind)。函数调用的参数传递是赋值,不是拷贝。

2,global和nonlocal语句

global语句用来声明一系列变量,这些变量会引用到当前模块的全局命名空间的变量(module-level namespace),如果该变量没有定义,也会在全局空间中添加这个变量。

global var1, var2

nonlocal语句(nonlocal是Python3.2引入的)

Python2.7中还没有nonlocal语句。nonlocal语句用来声明一系列的变量,这个声明会从声明处从里到外的namespace去搜寻这个变量(the nearest enclosing scope),直到模块的全局域(不包括全局域),找到了则引用这个命名空间的这个名字和对象,若作赋值操作,则直接改变外层域中的这个名字的绑定。nonlocal语句声明的变量不会在当前scope的namespace字典中加入一个key-value对,如果在外层域中没有找到,则如下报错。

>>>SyntaxError: no binding for nonlocal 'spam' found

一个nonlocal和global的测试例子

 1 def test():
 2     def do_local():
 3         spam = "local spam"
 4     def do_nonlocal():
 5         nonlocal spam     6         spam = "nonlocal spam"
 7     def do_global():
 8         global spam
 9         spam = "global spam"
10     spam = "test spam"
11     do_local()
12     print("after local assignment:", spam)   #输出:test spam
13     do_nonlocal()
14     print("after nonlocal asssignment:", spam)   #输出:nonlocal spam
15     do_global()
16     print("after global assignment:", spam)    #输出:nonlocal spam
17
18 test()
19 print("in global scope:", spam)  #输出:global spam

第5行的语句:nonlocal spam 没有在函数do_nonlocal()的域中创建一个变量,而是去引用到了外层的,10行定义的spam。

第8行的global spam,在全局域中创建了一个name,9行将其绑定在字符串常量对象"global spam"上。

跟进一步测试nonlocal

 1 def test():
 2     def do_nonlocal():
 3         nonlocal spam
 4         def do_nonlocal2():
 5             nonlocal spam
 6             spam = "nonlocal2 spam"  #修改了test()中spam的绑定
 7         do_nonlocal2()
 8     spam = "test spam"
 9     do_nonlocal()
10     print("after nonlocal2 asssignment:", spam)  #输出:nonlocal2 spam
11 test()

do_nonlocal2()中的spam引用的是其外面的二层,也就是test()函数域中的spam。

参考:

http://docs.python.org/3.3/tutorial/classes.html#python-scopes-and-namespaces   Python文档

http://docs.python.org/3.2/reference/simple_stmts.html  Python文档-simple statement

转载于:https://www.cnblogs.com/livingintruth/p/3296010.html

Python基础-作用域和命名空间(Scope and Namespace)相关推荐

  1. Python基础 F-03 函数-命名空间与作用域

    函数-命名空间与作用域 文章目录 函数-命名空间与作用域 一.命名空间 1.1.定义与作用 1.2.分类 1.4.生命周期 命名空间创建周期 命名空间结束周期 二.作用域 2.1.定义与作用 2.2. ...

  2. python基础(7)-函数命名空间作用域闭包

    函数 动态参数 *args 1 def sum(*args): 2 ''' 3 任何参数都会被args以元组的方式接收 4 ''' 5 print(type(args)) # result:<c ...

  3. python函数作用域_Python命名空间和作用域的基本认识和一点小魔法

    作为初学者,简单总结自己对Python命名空间(namespace)和作用域(scope)的认识. Python在名称空间搜寻变量和函数的顺序可以认为是: 函数内部 -> (嵌套)父函数内部 - ...

  4. python基础入门视频-Python基础入门视频课程——笔记

    Python基础,主讲:汤小洋 一.Python简介 1. Python是什么? ​ Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido van Rossum(龟叔)于1989年 ...

  5. 命名空间_python基础 13 类命名空间于对象、实例的命名空间,组合方法

    python基础 13 类命名空间于对象.实例的命名空间,组合方法 1.类命名空间于对象.实例的命名空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两 ...

  6. 九. Python基础(9)--命名空间, 作用域

    九. Python基础(9)--命名空间, 作用域 1 ● !a 与 not a 注意, C/C++可以用if !a表示if a == 0, 但是Python中只能用if not a来表示同样的意义. ...

  7. el 能否定义作用域变量_Python 基础知识全篇-命名空间和作用域

    命名空间 先看看官方文档的一段话: A namespace is a mapping from names to objects.Most namespaces are currently imple ...

  8. 【Python基础教程】变量的作用域详解

    变量作用域 Python 能够改变变量作用域的代码段是 def . class . lamda. if/elif/else.try/except/finally.for/while 并不能涉及变量作用 ...

  9. python函数作用域与闭包_python基础-08-内置函数、作用域、闭包、递归

    python基础-内置函数.作用域.闭包.递归 1.常见的内置函数 常见的内置函数: 查看内置函数: print(dir(__builtins__)) 常见函数 type() 数据类型 print() ...

最新文章

  1. CentOS查看主板型号、CPU、显卡、硬盘等信息
  2. Python基本语法_异常处理详解
  3. ADAS在车载导航设备上的应用
  4. 破除Odoo 菜单栏提示 99+
  5. clickhouse 子查询_Clickhouse 查询分布式表子查询 (Distributed Subqueries )
  6. PHP笔记-表格及分页功能
  7. 看完这些美食海报,你是不是又有灵感了?
  8. 8th,Jan Time Shedule_1st Day
  9. 高级 Vue 组件模式 (6)
  10. 程序设计基础(C语言)教学案例-序言
  11. 统计图源代码_openlayers4 入门开发系列结合 echarts4 实现统计图(附源码下载)
  12. 各个版本的sqlite-jdbc jar下载链接
  13. 如何在软件里显示编译时间?__DATE__和__TIME__
  14. 信息化管理系统在企业的应用
  15. Excel自定义格式日期计算问题
  16. 2020年9月程序员工资统计,平均14469元
  17. 应用泛函分析—距离空间
  18. 新时代知识产权创新发展与严格保护_保护知识产权?宣传强化治理——东安街道团结社区新时代文明实践站大力宣传《知识产权法》...
  19. 低版本系统兼容的ActionBar(三)自定义Item视图+进度条的实现+下拉导航+透明ActionBar...
  20. 吃什么食物对眼睛最好

热门文章

  1. css笔记——css 实现自定义按钮
  2. Hello Indigo
  3. jquery中邮箱地址 URL网站地址正则验证实例代码
  4. 【Codeforces #130 Div2】Solutions
  5. Oracle9i OCM认证实践课考试的一些说明
  6. javascript 将table导出 Excel ,可跨行跨列
  7. 网站三级分销数据库如何设计,简单案例
  8. Android 申请权限结果返回处理
  9. Android 2017-2018面试题详解
  10. java 基本数据类型和包装类型