python中,对于变量作用域的规定有些不一样。

在诸如C/C++、java等编程语言中,默认在函数的内部是能够直接訪问在函数外定义的全局变量的,可是这一点在python中就会有问题。以下是一个样例。

test.py:

#!/usr/bin/python

COUNT=1

def func():
COUNT = COUNT + 1 func()
Python test.py。会执行报错:
Traceback (most recent call last):
File "test.py", line 8, in <module>
func()
File "test.py", line 6, in func
COUNT = COUNT + 1
UnboundLocalError: local variable 'COUNT' referenced before assignment

“UnboundLocalError: local variable 'COUNT' referenced before assignment”的意思是变量COUNT在赋值之前被引用。

这里要知道python和其他编程语言不一样的地方。像C/C++之类的编程语言。变量名称实际上是代表的一块内存区域。对该变量赋值的意思就是将新的值放入该变量指定的内存区域。而对于python来说。全部的变量都是对内存区域的引用,对变量赋值相当于将变量引用的内存从一块区域改变到另外一块存放新值的区域

也就是说,C/C++中,变量名和内存区域的相应关系不会变,变的仅仅是相应内存中存放的值;而在python中,变量仅仅是对存放其值的内存区域的引用,变量值的改变不是由于变量指向的内存区域中的值发生了变化,而是变量引用了新的存放新值的内存区域。

python中的全部变量都是相当于java中的不可变的变量,不论什么一次值的改变都相应着变量引用内存区域的变化。

差别例如以下图1:

图1 变量的比較

python中有一个id函数,python中有一个id函数。help(id)能够看到它的说明。例如以下:

Help on built-in function id in module __builtin__:
id(...)
id(object) -> integer
Return the identity of an object. This is guaranteed to be unique among simultaneously existing objects.(Hint: it's the object's memory address.)
(END)

简单地说,id函数反应的是对象的内存地址,看以下的实验结果:

test.py:
#!/usr/bin/python COUNT = 1
for i in range(5):
COUNT = COUNT + 1
print id(COUNT) python test.py执行结果:
11031328
11031304
11031280
11031256
11031232

这里和上面图上说明的相吻合,python中每一次赋值都使变量引用的内存空间发生了改变。

回到上面“referenced before assignment”的错误,之所以会发生这样的错误是由于python在函数中发现对于COUNT变量的赋值。会将其加入到函数的局部命名空间(实际上,这是在函数执行到赋值操作之前发生的)。

进行赋值操作时。赋值操作符的右边引用了COUNT变量。而这时COUNT变量仅仅是被加入到了函数的局部命名空间,而没有被详细赋值,所以会发生上面的错误。实际上。这里问题就出在赋值操作的地方,由于有赋值操作导致该变量被加入到了函数的局部命名空间。假设没有赋值,仅仅是引用该变量,是没有什么问题的,例如以下:

test.py:
#!/usr/bin/python COUNT=1 def func():
temp = COUNT + 1
print "temp:",COUNT
print "COUNT:",COUNT func() python test.py执行结果:
temp: 1
COUNT: 1

这样,COUNT变量没有被加入到函数的局部命名空间,python解释器在函数的局部命名空间中没有查找到它。然后。python解释器会继续在全局的命名空间中查找,结果在全局命名空间中找到COUNT的定义并引用它的值,所以程序执行没有不论什么问题。

到这里你可能会问,难道在函数中没法改动全局变量的值吗?不是的,假设要在函数中改动全局变量的值,就要在函数中对该变量进行global声明,以告诉python解释器,该变量是全局命名空间中的,例如以下:

test.py:
#!/usr/bin/python COUNT=1 def func():
global COUNT
COUNT = COUNT + 1
print "COUNT:",COUNT func() python test.py执行结果:
COUNT: 2

python中的全局变量和局部变量的更多相关文章

  1. Python中的全局变量与局部变量的区别

    全局变量与局部变量两者的本质区别就是在于作用域 用通俗的话来理解的话, 全局变量是在整个py文件中声明,全局范围内都可以访问 局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地 ...

  2. python中的全局变量和局部变量(转)

    python中,对于变量作用域的规定有些不一样. 在诸如C/C++.java等编程语言中,默认在函数的内部是能够直接訪问在函数外定义的全局变量的,可是这一点在python中就会有问题.以下是一个样例. ...

  3. python中的全局变量、局部变量、实例变量

    1.全局变量:在模块内,在所有函数.类外面. 2.局部变量:在函数内,在类方法内(未加self修饰的) 3.静态变量:在类内,但不在类方法内.[共同类所有,值改变后,之后所有的实例对象也改变] 4.实 ...

  4. python线程中的全局变量与局部变量

    在python多线程开发中,全局变量是多个线程共享的数据,局部变量是各自线程的,非共享的. 如下几种写法都是可以的: 第一种:将列表当成参数传递给线程 from threading import Th ...

  5. python函数的 全局变量与局部变量

    一.函数的全局变量 1.什么是全局变量 顶着头开始写,没有任何缩进,在py文件的任何位置都能调用 #!/usr/bin/env python # _*_ coding:utf8 _*_ name=&q ...

  6. 总结javascript中的全局变量和局部变量的区别以及声明函数和调用函数的区别

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="utf-8&quo ...

  7. SQL中的全局变量和局部变量(@@/@)

    在SQL中,我们常常使用临时表来存储临时结果,对于结果是一个集合的情况,这种方法非常实用,但当结果仅仅是一个数据或者是几个数据时,还要去建一个表,显得就比较麻烦,另外,当一个SQL语句中的某些元素经常 ...

  8. python中的全局变量

    1. 在函数中定义的局部变量如果和全局变量同名,则会使用局部变量(即隐藏全局变量). 示例: x = 1 def func(): x = 2 print x func() print x 运行结果: ...

  9. Java中的全局变量与局部变量

    全局变量:也叫成员变量,是指在类中定义的变量:它在整个类中都有效 全局变量又可分为:类变量和实例变量 1.类变量:又叫静态变量  用static修饰  它可以直接用类名调用  也可以用对象调用   而 ...

随机推荐

  1. 旁路、去耦、Bulk以及耦合电容的作用与区别

    在硬件设计中有很多种电容,各种电容的功能.种类和电容容值各不相同.按照功能划分的话,最重要的几种电容分别称为:去耦电容(De-coupling Capacitor),旁路电容(Bypass Capac ...

  2. JavaScript判断该对象是否为数组

    typeof 用来检测数据类型,Function, String, Number, Undefined都可以使用typeof来判断. function test(){} console.log(typ ...

  3. maven无法下载oracle驱动包

    由于版权问题,在中央仓库是没有oracle的jdbc驱动的,可以手动下载到本地或者在oracle安装目录的jdbc目录中找到对应的jar,然后通过以下命令安装到本地仓库 mvn install:ins ...

  4. Go 知识点

    必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main. package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包. main 函 ...

  5. 18.23 inline函数功能

    GUN的C关键字,在函数定义中函数返回类型前加上关键字inline,可以把函数指定为内联函数.关键字inline必须与函数定义放在一起才能使函数成为内联,仅仅将inline放在函数声明前面不起任何作用 ...

  6. [zz] Python 3.7 anaconda environment - import _ssl DLL load fail error

    https://stackoverflow.com/questions/54175042/python-3-7-anaconda-environment-import-ssl-dll-load-fai ...

  7. 承接小程序外包 微信小程序外包 H5外包 就找北京动点软件

    承接小程序外包 微信小程序外包 H5外包 就找北京动点软件 长年承接微信小程序.微信公众号开发 全职的H5开发团队,开发过几十款微信小程序公众号案例 欢迎来电咨询 QQ:372900288 微信:li ...

  8. 关于C6678的网口问题

    1.C6678 Keystone1架构的GbE switch subsystem如图所示: 2.从图中可以看到MAC层与物理层PHY芯片的连接接口是由SGMII+SerDES构成,SGMII是以太网M ...

  9. python3学习笔记12(变量作用域)

    变量作用域 参考http://www.runoob.com/python3/python3-function.html Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量 ...

  10. OkGo3.0 --真实项目使用和二次封装(转)

    转载:https://blog.csdn.net/jiushiwo12340/article/details/79011480  11.OkGo3.0真实项目使用和二次封装: ====  11.OkG ...