问题1:变量?
答:
变量创建:一个变量,如a,当代码第一次给它赋值时就创建了它。
变量类型:变量永远不会拥有任何和它关联的类型信息或约束。类型的概念存在于对象中,而不是变量中。
变量使用:当变量出现在表达式中时,它会马上被当前引用的对象所代替,无论这个对象是什么类型。
问题2:如何理解>>> a = 3?
答:
创建一个对象来代表值3
创建一个变量a,如果它还没有被创建的话
将变量与新的对象3相连接
注:如图所示,变量和对象保存在内存中的不同部分,并通过连接相关联。变量总是连接到对象。在Python中从变量到对象的连接称为引用。引用是一种关系,通过内存中的指针形式来实现。
问题3:对象?
答:每一个对象都有两个标准的头部信息:类型标志符(type designator)标识这个对象的类型;引用的计数器(reference counter)决定何时回收这个对象。
类型标志符:对象知道自己的类型,每个对象都包含一个头部信息,其中标记了这个对象的类型。例如,整数3,包含了值3以及一个标志符,告诉Python这是一个整数对象(标志符是一个指向int的对象的指针)。
引用计数器:每个对象中保留了一个计数器,计数器记录当前指向该对象的引用数目。一旦(精确到同一时间)这个计数器被设置为零,这个对象的内存空间就会自动回收。
问题4:垃圾回收?
答:在Python中,每当一个变量名被赋予一个新的对象,如果原来的对象没有被其他的变量名或者对象所引用的话,那么之前的那个对象占用的空间就会被回收。
问题5:共享引用?
答:
输入这两行命令后,第二行命令会使Python创建变量b,变量a也在使用并且在这里没有被赋值,所以a,b都是对对象3的引用。
问题6:在原位置修改?
答:有一些对象和操作(列表、字典和集合)确实可以在原位置改变对象。
>>> L1 = [1,2,3]
>>> L2 = L1
>>> L1[0] = 24
[24, 2, 3]
[24, 2, 3]
注:上面语句中没有对L2进行修改,但是L2的值也跟着改变了。这是因为列表对象可以在原位置改变,当多个对列表对象的引用有一个使得列表在原位置改变,则其他引用的值也会跟着改变。
问题7:避免原位置修改?
答:如果想要避免上面的情况,可以请求Python复制(copy)对象,而不是创建引用。复制一个列表有很多种方法,包括使用内置list函数或者标准库的copy模块。最常用的方法就是从头到尾的分片。
>>> L1 = [1,2,3]
>>> L2 = L1[:]
>>> L1[0] = 24
[24, 2, 3]
[1, 2, 3]
注:这里,对L1修改不会影响L2,因为L2引用的是L1所引用对象的一个副本,而不是对象本身。也就是说,两个变量指向不同的内存区域。
问题8:相等?
答:Python中有'' == ''运算符和'' is ''运算符两种方法去检查是否相等。
>>> L = [1,2,3]
>>> L == M
True
>>> L is M
True
注:'' == ''运算符是测试两个被引用的对象是否有相同的值;'' is ''运算符是检查两个变量名是否指向同一个对象,即检查指针是否一样。
>>> L = [1,2,3]
>>> M = [1,2,3]
>>> L == M
True
>>> L is M
False
注:在Python中,小的整数和字符串被缓存并复用。
>>> X = 42
>>> Y = 42
>>> X == Y
True
>>> X is Y
True
所以is告诉我们X和Y引用了一个相同的对象。前面提及的“垃圾回收”对于某些特定的类型可能不是完全按照条规。
领取专属 10元无门槛券
私享最新 技术干货