python虽然没有指针的概念,但是对象、引用、地址这些内容还是存在的,尤其是像列表对象、某类型对象的引用上,搞清楚对象变量的复制和赋值很有必要,不然容易出现“莫名其妙”的错误。
目录
认清对象、引用、地址(直接以“=”赋值变量)
以列表为例
python中给一个变量a
赋值列表实际上是创建了一个列表对象,并将该列表的地址赋值给a
,而变量a此时就成为了这个列表对象的引用。当用a
给变量b
赋值时,其实只是把这个列表对象的地址赋值给了b,即a
和b
都成为了该对象的引用,因此直接对a
或b
进行修改,都将使该对象发生变化,下面给出一段代码示例:
a = ["abc","bcd","cde",1,2,3] #创建了一个对象并用变量a引用它
b = a #将a赋值给b,让b和a都同时作为列表对象的引用
print("a=",a,"b=",b) #输出a,b列表中的内容
print("a:",type(a),id(a),"b:",type(b),id(b))#输出a,b的类型和地址
b[0] = 0 #通过引用b将列表第一个元素赋值为0
a.remove(3) #通过引用a将列表中第一个值为3的元素删除
print("修改后:")
print("a=",a,"b=",b) #输出a,b列表中的内容
print("a:",type(a),id(a),"b:",type(b),id(b))#输出a,b的类型和地址
a = ["a","new","list"] #创建一个新的对象赋值给a,即让变量a成为新列表对象的引用
print("a=",a,"b=",b) #输出a,b列表中的内容
print("a:",type(a),id(a),"b:",type(b),id(b))#输出a,b的类型和地址
运行结果为:
a= ['abc', 'bcd', 'cde', 1, 2, 3] b= ['abc', 'bcd', 'cde', 1, 2, 3]
a: <class 'list'> 2072617426752 b: <class 'list'> 2072617426752
修改后:
a= [0, 'bcd', 'cde', 1, 2] b= [0, 'bcd', 'cde', 1, 2]
a: <class 'list'> 2072617426752 b: <class 'list'> 2072617426752
a= ['a', 'new', 'list'] b= [0, 'bcd', 'cde', 1, 2]
a: <class 'list'> 2072617436224 b: <class 'list'> 2072617426752
可以看到,一开始a和b共同代表了创建的列表["abc","bcd","cde",1,2,3]
,两个变量输出的内容、类型、地址都是完全一样的,用两个变量均可以对该列表进行修改,即a
和b
会互相影响。而后面给a
另外赋值一个新的列表对象后,a
和b
就分别引用不同的对象了,两者在之后就不会互相影响了。
以自定义类为例
对于python中的类,包括自定义的类,所创建的对象也是类似的,给变量赋值仅仅是将对象地址给到变量,让变量成为该对象的引用,看下面的一段示例代码和结果就很好理解了:
class AClass:
def __init__(self):
self.alist = [1,2,3,"ab","cd"]
self.aString = "abcdef"
a = AClass()
b = a
print("a:",a)
print("a.alist:",a.alist)
print("a.aString:",a.aString)
print("b:",b)
print("b.alist:",b.alist)
print("b.aString:",b.aString)
b.aString = 0
b.alist = 0
print("修改后:")
print("a:",a)