0%

Python_变量理解

精准变量理解

变量是不是盒子?

很多人将变量理解为盒子,其内部包裹着对象,然而这是不准确的。请看下面代码:

1
2
3
4
5
a = [1,2,3]
b = a
a.append(4)
print(b)
# [1, 2, 3, 4]

代码中,a,b 是指向同一列表对象的变量,修改a指向的对象,b指向的对象也随之改变。如果按照盒子去理解,那么a,b应该是分割的,正确理解为变量就是便利贴。如图:

赋值语句的执行顺序
Python中的赋值语句,始终是先读右边,对象在右侧创建或者获取,然后才会绑定到左侧的变量上,就像为对象贴上了便利贴;

标识、相等性与别名

别名

别名就是引用对同一对象的变量名称;

1
2
3
4
5
6
7
8
9
10
11
a = [1 ,2 ,3]
b = a
c = [1 ,2 ,3]
print(id(a))
print(id(b))
print(id(c))
"""
15021560
15021560
15022720
"""

可以看到通过赋值操作,b与a指向同一对象,b就是a的别名;而c指向的对象虽然内部元素与a一致,但是指向不同的对象,所以c不是a的别名。

相等性:is 与 ==

这里大家都比较清除,Python中提供了两种相等性判定操作符:其中is用来判断两变量的标识(地址)。而==用来判断两对象的内部结构是否一致。

TIPS: ==是一个语法糖,其等价于a.__eq__(b);而基类object中equal方法也是比较的双方的标识,结果与is是一样,一般的子类一般会重写此方法。

元组的相对不可变性

首先我们要明确元组与列表等是一样的,其存储的是对象的引用。如果元组中的元素是可变的,那么即使元组不变(仍然指向那个内存地址),其内部元素仍然可变。也就是说元组的不可变性指的是数据结构的物理内容不可变(保存的引用不可变),与引用的对象无关。感觉就像是把指针冻住了,而没有冻住指向的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
t1 = (1, 2, [10 ,20])
t2 = (1, 2, [10 ,20])
print(t1 == t2) # True , 俩元组对象内部内容一致
print(t1 is t2) # False,不是同一个对象
print(id(t1)) # 查看t1对象改变前的内存地址
t1[-1].append(30)
print(id(t1)) # 查看t1对象改变后的内存地址,即使内部元素已经变化而地址没有变
print(t1)
print(t1 == t2)
"""
True
False
46182928
46182928
(1, 2, [10, 20, 30])
False
"""

总结

这里主要总结了Python中该如何理解变量,结论就是理解为便利贴。指向同一对象的便利贴之间的关系为别名。顺便讨论了在Python中常用到的相等性判断方法,延展出元组的相对不可变性。

总的来说,这一部分内容相对简单,更多的是在实践中检验。