总所周知,Python中一切皆对象(object),都可以使用Python内置的type()
和id()
对其进行追踪。而在对象中,可以根据可变和不可变将其分为可变对象和不可变对象。
在Python中,常见的可变类型有list
,dict
,常见的不可变类型有数字(int, float),字符串(string)和tuple
不可变类型
先来看个例子:
>>> a = 1
>>> id(a)
30702344L
>>> a = 2
>>> id(a)
30702320L
>>> id(1)
30702344L
>>> id(a+1)
30702320L
>>> id(a+1) == id(3)
True
>>> string1 = 'Hello, World! Welcome to see Python's World'
>>> string2 = 'Hello, World! Welcome to see Python's World'
>>> id(string1) == id(string2)
True
可见,对于所有值为3的数,其在内存空间中指向的是同一片空间。而当变量值改变之后,其指向的空间也就发生了改变 这就是不可变的含义。
需要注意的是字符串(string)
是不可变类型,但字符
却不是不可变类型。可以看下面的例子:
>>> char1 = 'a'
>>> string1 = 'Hello, Python!'
>>> id(string1) == id('Hello, Python!')
True
>>> id(char1) == id('a')
False
可变类型
先来看个例子:
>>> list1 = [1,2]
>>> id(list1)
39504200L
>>> list1.append(3)
[1,2,3]
>>> id(list1)
39504200L
可见当list
发生变化时,变量所指向的内存空间并没有发生变化。
可变,不可变的影响、区别
>>> def test1(somearg = []):
··· somearg.append(7)
··· print somearg
>>> def test2(somearg = 0):
··· somearg += 1
``` print somearg
>>> for _ in range(3):
··· test1()
··· test2()
[7]
1
[7, 7]
1
[7, 7, 7]
1
在这个例子中对于默认参数somearg = []
的处理方式显然不是我们所期望的,它实质上并没有在每次运行时准备一个全新的空list
,那我们应该怎么处理呢?
>>> def test1(somearg = None):
··· if not somearg:
··· somearg = []
``` somearg.append(7)
``` print somearg
>>> for _ in range(3):
··· test1()
[7]
[7]
[7]