Python 极简核心:变量
0. 变量
首先,一定要理解清楚变量的真正含义:
在Python中,变量是对对象的引用。而赋值操作就是建立一个对象的引用。
In Python, variables are references to objects and any variable can reference any object.
1. 变量的命名
最基本的变量命名规则这里就不讲了,下面记录一些变量命名的一些误区。
- 使用Python内置函数名作变量名
>>> abs(-10)
10
>>> abs = 10
>>> abs(-10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
2. 变量的命名空间:作用域
变量的命名空间,也叫作作用域。(命名空间=作用域)
主要有以下这几点要注意:
2.1 命名空间的定义
作用域:程序创建、访问、改变一个变量时,都是在一个保存该变量的空间内进行,这个空间为命名空间,即作用域。
python作用域是静态的,变量被赋值、创建的位置决定了其被访问的范围,即变量作用域由其所在位置决定。
2.2 命名空间的前提
Python中,作用域的概念仅仅存在于:当变量在Module(模块)、Class(类)、def(函数) 中定义的时候
理解这一点至关重要! 对于LEGB原则
准确、快速的理解很有帮助。
2.3 命名空间的解析机制
LEGB规定了作用域的查找顺序 :
local
—>enclosing function locals
—>global
—>builtin
Python 的变量名解析机制也称为 LEGB 法则,具体如下: 当在函数中使用未确定的变量名时,Python 搜索 4
个作用域:本地作用域(L),之后是上一层嵌套结构中 def 或 lambda
的本地作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,Python会报错的。
更详细部分总结在:Python:变量的作用域与LEGB原则
3. 变量的创建:赋值
再次强调变量的内涵:
变量是标注(引用),而不是盒子(储存空间)。
- 变量不是储存对象的盒子,而是贴在对象上的便利贴
- 是把变量分配给对象,而不是把对象分配给变量
下面介绍变量赋值中容易出bug的几点。
3.1 将”变化的量“赋值给变量
>>> b = 0
>>> a = b
>>> a
0
>>> b = 1
>>> a
0
变量是一个标记/标注,指向的是内存中具体的值。当我们将一个标记赋值给另一个标记的时候,应该是让其指向另一个标记的内存,而不是指向标记。
即,要注意:将”变量“(可能变化的量)赋值给Python变量时,该Python变量就已经固定不会再变了,除非重新赋值。
容易出现bug的原因:以为a会随着b发生改变。
3.2 将函数赋值给变量
将函数赋值给变量有两种方式,一不注意很容易出错。
a = f
a = f()
这两种方式到底那种正确?
>>> a = abs
>>> a(-2)
2
>>> b = abs()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (0 given)
>>> b = abs(-1)
>>> b
1
从上面可以看出:
-
a = abs
的意思是:将a指向函数abs本身,也即将函数abs本身赋值给变量a -
b = abs(-1)
的意思:将b指向函数的返回值,也即将函数abs(-1)的返回值赋值给变量b
因此,我们就会明白闭包的外部函数返回的是内部函数(而不是带括号的函数返回值)
参考: