Python和Scala的变量作用域
2018-03-16 13:22
369 查看
今天聊的主题是变量作用域,也就是定义的变量可以使用的一片区域。变量通常意义指的是一个存储着标识符和标识符所关联的值的空间。在程序的运行过程中,标识符会绑定上相应的值,在某些情况下,标识符对应的值是可以发生变化的。什么是变量作用域呢?在维基上给出的定义是“The scope of a variable describes where in a program's text the variable may be used, while the extent (or lifetime) describes when in a program's execution a variable has a (meaningful) value. ”简而言之就是两点,在何处可以使用变量以及标识符绑定的值生存多久。那么在具体的语言Scala和Python是如何处理变量作用域的呢?
Scala:
Scala在变量声明时就确定了它的作用域范围,最常见的作用域是用一个花括号括起来的区域,这就是一个新的作用域。我们可以看一个简单的例子:
Python的变量不同于Scala,它的变量实际上一个字符串对象,和它所指向的对象关联。Python的作用域规则最出名的就是LEGB,这四个字母的含义代表着Python的对于变量的查找顺序locals -> enclosing -> globals -> builtins。这代表着如下例子是可以运行的:
Scala:
Scala在变量声明时就确定了它的作用域范围,最常见的作用域是用一个花括号括起来的区域,这就是一个新的作用域。我们可以看一个简单的例子:
object variable{ def main(args: Array[String]): Unit = { val a = 1 val a = 2 } }我们会发现编译器会报如下的错误:
Error:(8, 11) a is already defined as value a val a = 2意味着变量a一旦定义好就不能在相同的作用域再次定义了相同名字的变量,除非我们又新建了一个作用域:
object variable{ def main(args: Array[String]): Unit = { val a = 1; { val a = 2 println(a) } println(a) } }这样就能正常输出了,因为两次定义的变量a都在不同的作用域里。记住这里的分号是必须要加上的,否则Scala会认为大括号这里没有定义变量名。值得一提的是在Scala里的内嵌作用域的变量是会忽略外部作用域相同名称的变量,这一点在Scala的REPL中尤为明显,因为每一行代表着一个新的作用域。
scala> val a = 1 a: Int = 1 scala> val a = 2 a: Int = 2那么就容易理解函数和类的定义体的局部变量的含义了,例如:
object variable{ def main(args: Array[String]): Unit = { val y = 1 val b = test(2) print(x) } def test(x:Int):Int = {x+1;print(y)} }我们会发现这里的x只能在test内部使用,外部是无法获取的到x变量的,内部也无法获取外部的变量y。每次的函数调用,都意味着新的局部变量的诞生。Python:
Python的变量不同于Scala,它的变量实际上一个字符串对象,和它所指向的对象关联。Python的作用域规则最出名的就是LEGB,这四个字母的含义代表着Python的对于变量的查找顺序locals -> enclosing -> globals -> builtins。这代表着如下例子是可以运行的:
__builtins__.B = "B" G = "G" def test(): E = "E" def enclosing(): L = "L" print(L,E,G,B) enclosing() test()test()输出的结果就是L E G B。这四个变量代表着四个不同的作用域,不同于Scala内部作用域无法获取外部作用域变量,这里输出的结果表示函数的局部变量是可以获得外部作用域的变量。对此,《流畅的Python》作者给出的解释是这来源于Python的设计选择而不是缺陷。除此之外,Python会假定在函数定义体中赋值的变量都是局部变量。所以导致了下面奇特的print(b)
b = 6 def test1(a): print(a) print(b) b = 9 test1(2) 2 Traceback (most recent call last): File "<ipython-input-6-51aa2bbacb35>", line 1, in <module> test1(2) File "<ipython-input-5-b3b2a279f5d9>", line 4, in test1 print(b) UnboundLocalError: local variable 'b' referenced before assignment这里的b无法获得外部定义的b=6,如果我们把b = 9删除,就会发现b可以使用了。
def test2(a): print(a) print(b) test2(1) 1 6
http://www.aibbt.com/a/22274.html
相关文章推荐
- 讲解Python中for循环下的索引变量的作用域
- python 变量作用域
- python变量作用域
- python(变量作用域)
- 再谈python的变量作用域
- Python基础:11变量作用域和闭包
- python变量作用域
- 关于Python中的变量作用域
- Python语言(五)变量作用域
- python中变量作用域及嵌套作用域
- Python变量作用域
- 从文章《python31[变量的作用域+global]》想到的
- Python基本语法_变量作用域
- Python学习之变量的作用域
- python函数-变量作用域
- python 变量作用域
- python变量作用域
- Python中变量的作用域
- python ,java 变量作用域
- python变量作用域