python中的名称空间以及作用域分析

从Python解释器开始执行之后,就在内存中开辟一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读入内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量会储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

名称空间:存放名字与内存地址关系的一个空间

全局名称空间:在python代码运行时就创建的变量名与内存地址对应关系的空间

局部名称空间:函数或类在运行时临时开辟出来的内存空间

作用域:作用域就是能够起作用的范围(如变量名被引用)

在python中,作用域分为全局作用域局部作用域

全局作用域:包含内置名称空间以及全局名称空间,在python文件中任意位置都能被引用,全局有效。

局部作用域:局部名称空间,只在局部有效,如函数,类等

作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关

名称空间的加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

名称空间的取值顺序:局部命名空间->全局命名空间->内置命名空间

global:

声明一个全局变量。
在局部作用域中想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)。
def func():
global a #没有则创建一个全局变量
a = 3
func()
print(a) #3 count = 1
def search():
global count
count = 2
search()
print(count) #2 def foo():
a = 1
def bar():
global a
print(a)
bar()
foo() #报错 name 'a' is not defined
#这是由于foo中的a不是全局作用域中的变量,那么在bar中重新创建了一个全局变量a,但是没有给a赋值,所以爆出这个错误 #对可变数据类型(list,dict,set)可以直接引用不用通过global,但是不能对改变它的内存地址,可以增加、删除,但`l1=l1[1:3]`时,这样就修改了原来的内存地址,所以会报错。
li = [1,2,3]
dic = {'a':'b'} def change():
li.append('a')
dic['q'] = 'g'
print(dic)
print(li)
change()
print(li)
print(dic)

nonlocal:

不能修改全局变量。
在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。
def add_b():
b = 42
def do_global():
b = 10
print(b) #10 --------->1
def dd_nonlocal():
nonlocal b
b = b + 20
print(b) #30
dd_nonlocal()
print(b) #30 -------------2
do_global()
print(b) #42
add_b()
#由于dd_nonlocal中声明的变量是从do_global中引用来的,所以在函数do_global中以及里面嵌套的函数中,都是相同的变量b,同时代码是从上到下执行,所以1出的b还没改变,还是10,但是2处的b已经改变了 a = 1
def foo():
print(a)
def bar():
nonlocal a
print(a)
bar()
foo() #SyntaxError: no binding for nonlocal 'a' found
#报错是由于nonlocal只能定义局部变量,此时的a是全局变量,所以报错

globals():查看全局作用域中的变量

locals():查看当前作用域中的变量

同时需要注意,在局部作用域中只能对全局变量进行引用,但是不能修改,这个修改只指的是不能对被引用的变量的内存地址进行改变,

python中的作用域与名称空间的更多相关文章

  1. 搞懂Python的类和对象名称空间

    代码块的分类 python中分几种代码块类型,它们都有自己的作用域,或者说名称空间: 文件或模块整体是一个代码块,名称空间为全局范围 函数代码块,名称空间为函数自身范围,是本地作用域,在全局范围的内层 ...

  2. 论python中的作用域

    编程语言从早至今,可以分为面向过程编程.面向函数编程和面向对象编程.BASIC语言是典型的面向过程编程的语言,C语言支持面向函数编程,但不支持面向对象,JAVA只支持面向对象编程,python同时支持 ...

  3. Python中的作用域

    Python中的作用域 Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定的. 当 Python 遇到一个变量的话他会按照这样的顺序进行搜索: 本地作用域(Local)→当前作用域被嵌 ...

  4. 同一个POD中默认共享哪些名称空间

    如果通过POD的形式来启动多个容器那么它们的名称空间会是共享的么,所以我这里讨论是在默认情况下同一个POD的不同容器的哪些名称空间是打通的.这里先说一下结论,共享的是UTS.IPC.NET.USER. ...

  5. 《Python》 函数进阶和名称空间作用域

    函数进阶: 一.动态参数:*args  **kwargs *args是元祖形式,接收除去键值对以外的所有参数 # args可以换成任意变量名,约定俗成用args **kwargs接收的只是键值对的参数 ...

  6. Python 函数对象-函数嵌套-名称空间与作用域-闭包函数

    今日内容: 1. 函数对象 函数是第一类对象: 指的是函数名指向的值可以被当中数据去使用 1.可以被引用 2.可以当做参数传给另一个函数 3.可以当做一个函数的返回值 4.可以当做容器类型的元素 2. ...

  7. python之函数对象、名称空间、嵌套、作用域、闭包

    函数对象 # 函数名就是存放了函数的内存地址,存放了内存地址的变量都是对象,即 函数名 就是 函数对象​# 函数对应的原因# 1 可以直接被引用# 2 可以当作函数参数传递# 3 可以作为函数的返回值 ...

  8. python 函数动态参数,名称空间,global,nonlocal

    ##################################总结######################################动态参数 *args:位置参数动态传参,接收到的是元 ...

  9. python中的作用域以及内置函数globals()-全局变量、locals()-局部变量

    在python中,函数会创建一个自己的作用域,也称为为命名空间.这意味着在函数内部访问某个变量时,函数会优先在自己的命名空间中寻找. 通过内置函数globals()返回的是python解释器能知道的变 ...

随机推荐

  1. linux查看网络链接状况命令netstat

    linux查看网络链接状况命令 netstat 参数如下: -a 显示所有socket,包括正在监听的. -c 每隔1秒就重新显示一遍,直到用户中断它. -i 显示所有网络接口的信息,格式同“ifco ...

  2. flash、js 函数 互相调用

    js调用flex函数 flex 利用ExternalInterface.addCallback(“注册的方法名”,As中的函数名)进行注册 js中,用document.getElementById(“ ...

  3. 畅通工程再续 (kruskal算法的延续)

    个人心得:这题其实跟上一题没什么区别,自己想办法把坐标啥的都给转换为对应的图形模样就好了 相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实 ...

  4. LeetCode Can Place Flowers

    原题链接在这里:https://leetcode.com/problems/can-place-flowers/description/ 题目: Suppose you have a long flo ...

  5. deque容器

    一.deque容器基本概念 deque是“double-ended queue”的缩写,和vector一样,deque也支持随机存取.vector是单向开口的连续性空间,deque则是一种双向开口的连 ...

  6. 为什么是2MSL而不是MSL?

    为什么等待2MSL,从TIME_WAIT到CLOSE? 在Client发送出最后的ACK回复,但该ACK可能丢失.Server如果没有收到ACK,将不断重复发送FIN片段.所以Client不能立即关闭 ...

  7. openTSDB+HBase+ZK遇到的坑汇总

    1.zookeeper返回的hbase地址是hostname,外网如何访问? 如果需要直接访问zk获取hbase地址进而访问,目前需要本机配置host ip  hostname 如果是要长期解决方法, ...

  8. QrCode C#生成二维码 及JavaScript生成二维码

    一 C#的二维码    示例: class Program { static void Main(string[] args) { QrEncoder qrEncoder = new QrEncode ...

  9. 通过maven的jar包库找到对应的jar包。

    查找连接: http://search.maven.org/ 查找实例 http://search.maven.org/#search|ga|1|a%3A%22log4j%22

  10. HDU5692(dfs序+线段树)

    Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...