Python进阶之路(二),命名空间namespace

引言

:在通常认知中,变量是一段具有特定格式的内存,变量名是内存别名,因为在编码阶段,无法确定内存的具体位置,故事用名称层符号代替.
注意:变量名和指针不同

接下来,静态编译和动态解释性语言对于变量名的处理方式完全不同,静态编译器或连接器会以固定地址,或者直接间接寻址执行代替变量名,也就是说变量名不参与执行过程,可以被剔除 ;但是在解释性语言中,名字和对象通常是两个运行期试题,名字不但有自己的类型,还需要分配内存,并且介入执行过程,甚至可以说,名字才是动态模型的基础.(比如 C#,JAVA,Python,PhP都是动态语言).

如果将内存寻址比喻成为顾客按照编号寻找服务柜台,那么名字就是一个接待员,任何时候,顾客都只能够通过他间接与目标服务互动.从表面看这好像是高级会员才有的东西,但是实际上增加了中间环节和额外的开销,于性能不利,但是好处是,接待员和服务之间拥有更多的调整空间,可以用来增加代理和安全机制,甚至为缓存管理提供机会,后续会更新出有关元变成的内容.

当然名字必须和目标对象关联起来才有意义.

In [1]: x                                                                                                                                                                                    
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-6fcf9dfbd479> in <module>
----> 1 x

NameError: name 'x' is not defined

In [2]:  

最直接的关联操作就是赋值,然后对名字的引用都被解释为对目标对象进行操作

In [2]: x = 100                                                                                                                                                                              

In [3]: x                                                                                                                                                                                    
Out[3]: 100

In [4]: x +=2                                                                                                                                                                                

In [5]: x                                                                                                                                                                                    
Out[5]: 102

In [6]:  

赋值步骤,

  1. 将准备好右值目标对象(100)
  2. 准备好名字 (x)
  3. 在名字空间里为两者建立关联(namespace {x:100})

即便如此,名字与目标对象之间也仅仅是引用关联,名字只负责找人,但对于此人一无所知.只有在运行期间才知道名字引用的目标类型,所以说Python是一种动态语法/

name have no type,but objects do


名字空间

名字空间(namespace) 是上下文环境中专门用来储存名字和目标引用关联的容器,如图所示


在这里插入图片描述

对于Python而言,每个模块(源码文件)都有一个全局名字空间,而根据代码作用域,又有当前名字或者本地名字空间一说.如果在模块级别执行,那么当前名字空间和全局名字空间相同,但是在函数中,当前名字就是专值函数作用域.


名字空间默认使用字典(dict) 数据结构,有多个键值(key/value) 组成.
内置函数globals和locals分别返回全局名字空间,和本地名字空间字典.


In [6]: x = 100                                                                                                                                                                              

In [7]: id(globals())                                                                                                                                                                        
Out[7]: 140077279009480

In [8]: id(locals())                                                                                                                                                                         
Out[8]: 140077279009480

In [9]: globals()                                                                                                                                                                            
Out[9]: 
{'In': ['',
  'x',
  'x = 100',
  ........


In [11]: def test(): 
    ...:     x = 'hello world' 
    ...:     print(locals())       # 指向本地命名空间
    ...:     print("locals:",id(locals())) 
    ...:     print("globals",id(globals()))  # 指向全局命名空间
    ...:    
    ...:                                                                                                                                                                                     

In [12]: test()        # 在函数作用域调用                                                                                                                                                              
{'x': 'hello world'}   # 此时,locals 输入函数名字空间
locals: 140077240118024 # locals != globals
globals 140077279009480 


可见,globals 总是固定指向模块名字空间,而locals 则指向当前作用域环境

在这里插入图片描述

在初步了解后,我们甚至可以直接修改名字空间建立关联医用,这与传统变量定义方式有何不同.


In [17]: globals()["hello"] = "hello,world"                                                                                                                                                  

In [18]: globals()["number"] = 123455                                                                                                                                                        

In [19]: hello                                                                                                                                                                               
Out[19]: 'hello,world'

In [20]: number                                                                                                                                                                              
Out[20]: 123455


并非所有时候都能直接操作命名空间,函数执行使用缓存机制,可以直接修改本地名字空间未必有效,在正常编码时,应该尽可能避免直接修改名字空间


在名字空间的字典中,名字只是简单字符串主键,其自身数据结构里面没有任何目标对象信息,通过名字访问目标对象,无非是以名字为主键去字典中读取目标对象指针引用.也正因为如此,名字可以重新关联另外一个对象,完全不在于其类型是否与前任相同.

In [21]: x = 100                                                                                                                                                                             

In [22]: x                                                                                                                                                                                   
Out[22]: 100

In [23]: id(x)                                                                                                                                                                               
Out[23]: 10922592

In [24]: globals()                                                                                                                                                                           
Out[24]: 
{'In': ['',
  'x',
  'x = 100',
  ......


In [25]: x = "abc"                  #重新关联一个对象                                                                                                                                                         

In [26]: x                                                                                                                                                                                   
Out[26]: 'abc'

In [27]: id(x)                       # 通过输出的id可以看出关联新对象,并非修改原对象内容                                                                                                                                             
Out[27]: 140077358909568

In [28]: globals()                   # 名字空间的引用变更                                                                                                                                                        
Out[28]: 
{'In': ['',
  'x',
  'x = "abc",



赋值操作仅仅是让名字在命名空间中重新关联,并非是修改原对象


在这里插入图片描述

和一个名字只能够引用一个对象不同,单个对象可以拥有多个名字,无论是在相同或者不相同的名字空间中


一个人在公司中,他可以是老王,王大叔,王哥哥等..这时这个人在办公室中就拥有了多个名字,出了办公司,在全公司,(另外一个命名空间)范围中,他还可以有王处长,王老板等其他名字.

命名规则

名字应该有实际含义,并且阅读和理解的字母或者单词组合

  • 以字母或者下划线开头
  • 区分大小写
  • 不能够使用保留关键字
In [3]: x = "abc"                                                                                                                                                                            

In [4]: X = "1"                                                                                                                                                                              

In [5]: X is x                                                                                                                                                                               
Out[5]: False

In [6]:      

为了统一命名风格

  • 类型名称使用CapWords 格式
  • 模块文件名,函数,方法成员等使用lower_case_with格式
  • 全局变量名通常使用全部大写格式
  • 避免与内置变量或者标准库的常用类型同名,因为这样容易造成误解

尽管Python3 中可以使用汉字作为变量名,但是并不推荐


In [7]: import keyword                                                                                                                                                                       

In [8]: keyword.kwlist      # 打印出Python3中的保留关键词                                                                                                                                                                 
Out[8]: 
['False',
 'None',
 'True',
 'and',
 'as',
 'assert',
 'break',
 'class',
 'continue',
 'def',
 'del',
 'elif',
 'else',
 'except',
 'finally',
 'for',
 'from',
 'global',
 'if',
 'import',
 'in',
 'is',
 'lambda',
 'nonlocal',
 'not',
 'or',
 'pass',
 'raise',
 'return',
 'try',
 'while',
 'with',
 'yield']



注意 python3中print 不再是关键字,是一个函数,但是在python2中仍旧是保留关键字

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,082评论 1 32
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,504评论 1 51
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,149评论 0 9
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,727评论 2 9
  • 早泄是动物进化的结果。所以有点快的朋友就不要气馁了,你只是进化得比较好。 猴子办事都是越快越好,十几秒做完最好,因...
    老酒老刀阅读 915评论 3 8