Python的命名空间学习

1.对象
Python 一切皆对象,每个对象都具有 一个ID、一个类型、一个值;对象一旦建立,ID 便不会改变,可以直观的认为 ID 就是对象在内存中的地址

上例 a, b 共享了同一个 ID、同一个值、同一个类型。因此 a, b 表达的是同一个对象,但 a, b 又明显是不同的,比如一个叫 'a' 一个叫 'b'...既然是同一个对象,为什么又有不同的名字呢?难道名字不是对象的属性?

2.标识符
事实确实如此,这是 Python 比较特殊一点:如同'a' 'b' 这样的名称其实有一个共同的名字:identifier(注意不要与 ID 混淆了),中文名为“标识符”,来解释一下:
标识符:各类对象的名称,比如函数名、方法名、类名,变量名、常量名等。

在Python中赋值并不会直接复制数据,而只是将名称绑定到对象,对象本身是不知道也不需要关心(该关心这个的是程序猿)自己叫什么名字的。一个对象甚至可以指向不同的标识符,上例中的'a' 'b'便是如此。真正管理这些名子的事物就是本文的主角“命名空间”。
在Python中使用一个变量之前不需要先对其进行声明,但真正使用它之前,这个变量必须被绑定到某个对象上,而且名字绑定将在当前作用域中引入新变量,同时屏蔽外层作用域的同名变量,不论这个名字绑定发生在当前作用域中的哪个位置。

3.赋值(assignment)  
Assignments do not copy data — they just bind names to objects.
赋值操作不会拷贝,只是把名字和对象做一个绑定。也就是赋值语句是起一个绑定或重绑定的作用(bind or rebind)。函数调用的参数传递是赋值,不是拷贝。
《核心编程》在Python语音中,对象是通过引用传递的。在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用(并不是值)赋值给变量

Assignment rule
1.赋值语句通常隐式地会创建一个局部(local)变量,即便该变量名已存在于赋值语句发生的上一层作用域中;
2.如果没有 global 关键字声明变量,对一个变量的赋值总是认为该变量存在于最内层(innermost)的作用域中

4.命名空间
名空间(Namespace):名字(标识符)到对象的映射。
简而言之,命名空间可以理解为:记录对象和对象名字对应关系的空间;现今 Python 的大部分命名空间是通过字典来实现的,也即一个命名空间就是名字到对象的映射,标识符是键,对象则是值。

1.局部命名空间(local):指的是一个函数或者一个类所定义的名称空间;包括函数的参数、局部变量、类的属性等。
2.闭包命名空间(enclosing function):闭包函数 的名称空间(Python 3 引入)。
3.全局命名空间(global):读入一个模块(也即一个.py文档)后产生的名称空间。
4.内建命名空间(builtin):Python 解释器启动时自动载入__built__模块后所形成的名称空间;诸如 str/list/dict...等内置对象的名称就处于这里。
python程序执行期间会有2个或3个活动的命名空间(函数调用时有3个,函数调用结束后2个)。

4.1声明周期
Local(局部命名空间)在函数被调用时才被创建,但函数返回结果或抛出异常时被删除。(每一个递归函数都拥有自己的命名空间)。
Global(全局命名空间)在模块被加载时创建,通常一直保留直到python解释器退出。
Built-in(内建命名空间)在python解释器启动时创建,一直保留直到解释器退出。

各命名空间创建顺序:python解释器启动 ->创建内建命名空间 -> 加载模块 -> 创建全局命名空间 ->函数被调用 ->创建局部命名空间
各命名空间销毁顺序:函数调用结束 -> 销毁函数对应的局部命名空间 -> python虚拟机(解释器)退出 ->销毁全局命名空间 ->销毁内建命名空间
python解释器加载阶段会创建出内建命名空间、模块的全局命名空间,局部命名空间是在运行阶段函数被调用时动态创建出来的,函数调用结束动态的销毁的。

5.作用域
作用域(Scope):本质是一块文本区域,Python通过该文本区域可以直接访问相应的命名空间。
在python中只有模块,类和函数会引入新的作用域,其他代码是不会引入新的作用域的
#百度百科-作用域(scope),程序设计概念,通常来说,一段程序代码中所用到的名字并不是总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

直接访问:对一个变量名的引用会在所有namespace中查找该变量,而不是通过属性访问。
属性访问:所有名字后加.的都认为是属性访问。

因此可以简单的将作用域理解为“直接访问命名空间的一种实现”,具体而言:
(1).作用域内相应的命名空间可以被直接访问;
(2).只有作用域内的命名空间才可以被直接访问(因此并不是所有的命名空间都可以被直接访问)。

作用域按照变量的定义位置可以划分为4类:
    Local(函数内部)局部作用域
    Enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)
    Global(模块全局)全局作用域
    Built-in(内建)内建作用域

6.命名空间的生命周期
实际上,到这里其实还有一个重要的重要问题没有解决:“标识符并不是天生就在命名空间内的,命名空间也不是平白无故就产生的,那么命名空间是在什么时候被创建?又是在什么时候被删除的呢?”
规则有四:

    (1).内建命名空间在 Python 解释器启动时创建,之后会一直存在;
    (2).模块的全局命名空间在模块定义被读入时创建,通常模块命名空间也会保持到解释器退出。
    (3).函数调用时产生新的局部命名空间;函数返回结果、抛出异常时释放命名空间,每一次递归都生成一个命名空间。
    (4).标识符产生地点决定标识符所处的命名空间。

A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition.
Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations.-代码块,只有模块,函数,类才有

Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope. This means that the following will fail:

The class’s suite is then executed in a new execution frame (see Naming and binding), using a newly created local namespace and the original global namespace. (Usually, the suite contains mostly function definitions.) When the class’s suite finishes execution, its execution frame is discarded but its local namespace is saved. [4] A class object is then created using the inheritance list for the base classes and the saved local namespace for the attribute dictionary. The class name is bound to this class object in the original local namespace.

A code block is executed in an execution frame. A frame contains some administrative information (used for debugging) and determines where and how execution continues after the code block’s execution has completed.

在python中,一切都是对象,数字,字符串,函数,类都是对象,只有通过一个命名(变量名),才能摄取一个对象。

个人理解'='右边都可以被认为是对象

https://www.cnblogs.com/livingintruth/p/3296010.html
http://python.jobbole.com/86465/
http://python.jobbole.com/81367/
https://www.cnblogs.com/hbcb533/p/3674172.html
https://segmentfault.com/a/1190000004519811
https://www.cnblogs.com/zhangxinhe/p/6963462.html



  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值