可变对象和不可变对象

时间:2021-12-13 03:59:16

Python 在堆(heap)中分配的对象分为两类,可变对象和不可变对象

  • 可变对象 - 对象的内容是可变的 list, dict, set
""" 对象的内容发生变化时,变量的对象引用是不会变化的 """
dict = {"a1":1, "a2":2, "a3":3}
print "%s --> %d" % (dict, id(dict))

dict["a4"] = 4
print "%s --> %d" % (dict, id(dict))

# Output
# {'a1': 1, 'a3': 3, 'a2': 2} --> 42838752
# {'a1': 1, 'a3': 3, 'a2': 2, 'a4': 4} --> 42838752
  • 不可变对象 - 对象的内容不可变 int, string, float, tuple
""" 不可变对象而言,尽管对象本身不可变,但变量的对象引用是可变的 """
print "123 --> %d" % (id(123))

a = 123
print "a = 123 --> %d" % (id(a))

b = 123
print "b = 123 --> %d" % (id(b))

b = b+1
print "b = b + 1 --> %d" % (id(b))

# Output
# 123 --> 43153560
# a = 123 --> 43153560
# b = 123 --> 43153560
# b = b + 1 --> 43153548
  • 函数的参数传递

    python规定参数传递都是传递引用,也就是传递给函数的是原变量实际所指向的内存空间,修改的时候就会根据该引用的指向去修改该内存中的内容,所以在函数内改变了传递过来的参数的值的话,原来外部的变量也应该受到影响。但是python中有可变类型和不可变类型,这样的话,当传过来的是可变类型(list, dict)时,在函数内部修改就会影响函数外部的变量。而传入的是不可变类型时在函数内部修改改变量并不会影响函数外部的变量,因为修改的时候会先复制一份再修改

  • 示例代码

def test(a_int, b_list, c_str, d_dict):
a_int = a_int + 1
b_list.append(13)
c_str = c_str + "bbb"
d_dict["a4"] = 4

print "输出局部变量"
print 'outer a_int: %d' % (a_int)
print 'outer b_list: %s' % (b_list)
print 'outer c_str: %s' % (c_str)
print 'outer d_dict: %s\n' % (d_dict)


if __name__ == '__main__':
a_int = 5
b_list = [10, 11]
c_str = "aaa"
d_dict = {"a1":1,"a2":2,"a3":3}

# 函数调用
test(a_int, b_list, c_str, d_dict)

print "输出全局变量"
print 'outer a_int: %d' % (a_int)
print 'outer b_list: %s' % (b_list)
print 'outer c_str: %s' % (c_str)
print 'outer d_dict: %s' % (d_dict)

# Output ...

# 输出局部变量
# outer a_int: 6
# outer b_list: [10, 11, 13]
# outer c_str: aaabbb
# outer d_dict: {'a1': 1, 'a3': 3, 'a2': 2, 'a4': 4}

# 输出全局变量
# outer a_int: 5
# outer b_list: [10, 11, 13]
# outer c_str: aaa
# outer d_dict: {'a1': 1, 'a3': 3, 'a2': 2, 'a4': 4}
回到顶部