目录
重点::
- Python只有一种 assignment model,就是动态的 variable+object+reference模型
- 类型信息是跟object有关的,而variable可以引用任何object
- Python本身会缓存小的int和string数据
- 避免 in-place改变,需要提前copy
- 判断相等的方法有2种:
==
和is
Chap6 动态类型
6.1 无需声明类型
Python自己有一个dynamic typing model
. 类型是在runtime时候决定的。
6.1.1 Variable, Object, Reference
- 变量创建:直接赋值。Technically,Python detects some names before your code runs, but you can think of it as thoughinitial assignments make variables.
- 变量类型:变量本身不包含类型信息,信息包含在objects内
- 使用变量:当变量出现在表达式中时,它马上被替换成了实际的object来使用
a. 创建对象时的步骤
a = 3
- 创建一个表示3的对象
- 创建变量a
- 将a的引用指向这个对象3
虽然实际上, python为了优化,在内部会缓存和重用一些不变的对象,比如小的int和 string。
6.1.2 类型和objects有关,而不是variable
每个对象至少有2个标准的头部信息:
- type designator 来表示类型信息
- reference counter 为了垃圾回收
实际上来说,这个type designator
是一个指向实际类型对象的指针,比如int类型的对象,那么这个type designator
就是一个指向int object
的指针。
6.1.3 垃圾回收
对象内部当 reference counter
的指针为0的时候,就会被python的GC回收。
除了这个reference counter, python的 gc内部还有一个组件能够侦察循环引用的问题。
6.2 Shared Reference
上面这张图,就叫做shared reference.
6.2.1 Shared References and In-Place Changes
>>> L1 = [2, 3, 4] # A mutable object
>>> L2 = L1 # Make a reference to the same object
>>> L1[0] = 24 # An in-place change
为了避免inplace change 的影响,应该提前复制:
- 使用list函数创建一个新的:
old = list(new)
- 切片
- 对象.copy() 方法
copy
模块的copy
和deepcopy
方法
6.2.2 Shared References and Equality
>>> x = 42
>>> x = 'shrubbery' # Reclaim 42 now?
因为python会缓存小的int还有 string, 所以上面的42并不会被垃圾回收,而是在system table中,等待下次使用的时候调用;而其他大部分objects,都会在没有被引用之后立马被回收掉。
- Python内2种比较的方法:
- a == B : 值比较
- a is B : 引用比较
>>> L = [1, 2, 3]
>>> M = L # M and L reference the same object
>>> L == M # Same values
True
>>> L is M # Same objects
True
>>> L = [1, 2, 3]
>>> M = [1, 2, 3] # M and L reference different objects
>>> L == M # Same values
True
>>> L is M # Different objects
False
# 被缓存的数字的比较
>>> X = 42
>>> Y = 42 # Should be two different objects
>>> X == Y
True
>>> X is Y # Same object anyhow: caching at work!
True
可以使用下面的方法来查看object有几个引用:
>>> import sys
>>> sys.getrefcount(1) # 647 pointers to this shared piece of memory
647