Python中的变量名是在编译时就解析好的,换句话说,在编译时(也就是在交互控制台输入代码是或者import文件时),Python就已经决定一个变量应该是局部变量,还是全局变量。来看下面的例子:

>>>X = 99
>>>def test():
print(X) >>>test()
99

函数test里面引用的变量,根据作用域链查找法则(LEGB法则),查找到的是全局变量X的值。

>>>X = 99
>>>def test():
print(X)
X = 88 >>>test()
UnboundLocalError:local variable 'X' referenced before assignment # 报错

根据文章开头所说,Python决定一个变量时局部的,还是全局的,是在编译期,当编译到函数test时,看到了X = 88的赋值语句,因此,Python认为X在函数test里面应该是一个局部变量,所以,当test函数运行时,执行print(X)语句,发现局部变量X未赋值就被引用了,所以报错了。

事实上,在函数体内进行的任何赋值操作,包括=,import,嵌套的def定义,嵌套的class定义,等等,都会产生局部变量。在Python函数内部,局部变量和全局变量是无法共存的,只能存在一种:

>>>X = 99
>>>def test():
X = 88
global X >>>test()
>>>X # 输出的是88
88

在上面的例子中,Python在编译函数test的时,首先看到赋值语句X = 88,认定X应该是局部变量,但是,当继续往下时,发现了global X语句,这将X声明成了一个局部变量,因此,Python最终将test函数内部的X变量认定成一个全局变量,并最终运行时,改变了全局变量X的的值,最后打印的结果为88。

需要注意的是,如果global的声明晚于变量的使用,Python会产生警告:SyntaxWarning:name 'X' is assign to before global declaration

Python决定一个变量时局部的,还是全局的,是在编译期的更多相关文章

  1. java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

    java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 是引用对象的地址值不能变,引用变量所指向的对象的内容是可以改变. final变量永远指向这个对象,是一个常量指针,而 ...

  2. 10.使用final关键字修饰一个变量时...

    10.使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 答:引用不能变,不能将引用再次指向另一个新的对象,但引用所指向的对象中的内容是可以改变的. 补充: 1.对于基本类型,f ...

  3. 【Java面试题】2 Java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?超详细解析

    /* * 问题:使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变 * 答: * 使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的 ...

  4. 使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

    使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.例如,对于如下语句:final StringBuffer a=new StringBuffer( ...

  5. 面试题:使用finalkeyword修饰一个变量时,是引用不能变,还是引用的对象不能变?

    /* * 问题:使用finalkeyword修饰一个变量时,是引用不能变,还是引用的对象不能变 * 答: * 使用finalkeyword修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内 ...

  6. 使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

    使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.例如,对于如下语句: final StringBuilder a=new StringBuilder ...

  7. Java中Final修饰一个变量时,是引用不能变还是引用的对象不能变

    Java中,使用Final修饰一个变量,是引用不能变,还是引用对象不能变? 是引用对象的地址不能变,引用变量所指的对象的内容可以改变. final变量永远指向这个对象,是一个常量指针,而不是指向常量的 ...

  8. shell 脚本中将输出内容赋值给一个变量时的换行问题

    for ((i=0; i<4; i++) do ....... done 如果使用 echo $a 输出变量,则变量中的 换行都会被忽略掉,所有内容输出到一行 而使用 echo "$a ...

  9. Python学习之变量的作用域

    学习地址:http://www.jianshu.com/p/17a9d8584530 1.变量作用域LEGB 1.1变量的作用域 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空 ...

随机推荐

  1. 【读书笔记 - Effective Java】04. 通过私有构造器强化不可实例化的能力

    工具类(utility class)不希望被实例化,比如只包含静态方法和静态域的类.为了这个目的,需要让这个类包含一个私有构造器. // 私有构造器示例 public class UtilityCla ...

  2. 纯JS实现轮播图特效——详解

    <div id="slider"> <div id="sliderImgs"> <img src="img/mi04.j ...

  3. 颜色rgba、16进制、10进制互相装换

    rgba转16进制: function RGBToHex(rgb){ var regexp = /[0-9]{0,3}/g; var re = rgb.match(regexp);//利用正则表达式去 ...

  4. tp5.1路由报错No input file specified.

    问题: 按照官方教安装了框架,打开首页没问题,可是安装教程路由规则打开 "http://127.0.0.1/hello/2" 时, 却报错误  "No input fil ...

  5. django模板的变量,标签,过滤器和自定义过滤器,注释

    模板的作用是计算并输出: {{ 变量}} 当模版引擎遇到点如book.title,会按照下列顺序解析: 1.字典book['title'] 2.先属性后方法,将book当作对象,查找属性title,如 ...

  6. Leecode刷题之旅-C语言/python-202快乐数

    /* * @lc app=leetcode.cn id=202 lang=c * * [202] 快乐数 * * https://leetcode-cn.com/problems/happy-numb ...

  7. PHP.48-TP框架商城应用实例-后台23-权限管理-权限验证

    权限验证 1.登录控制器 2.通过tp验证码类生成验证码图片 3.在管理员模型增加登录验证规则 4.后台中所有的控制器必须先登录才能访问 思路:在访问任何一个控制器之前都判断一个session即可,= ...

  8. Unknown host 'services.gradle.org' 解决方法

    报错如下: Unknown host 'services.gradle.org'. You may need to adjust the proxy settings in Gradle. Learn ...

  9. url和uri的一些问题

    一 url和uri的区别: uri: uniform resource identifier,统一资源标识符. url: uniform resource locator,统一资源定位符. 做一个类比 ...

  10. 问题:MongoDB C# driver异常:Truncation resulted in data loss

    问题描述: 原因分析: MongoDB C#驱动在读取数据记录遇到数值类型字段时,如果没有设置允许截断,将抛出TruncationException. 解决方法: [BsonRepresentatio ...