python数据可变与不可变类型,以及函数作用域

python的数据类型分为可变与不可变类型,在六大数据类型中,数字,字符串,元组为不可变类型,列表,字典,集合为可变类型
python数据的引用其实是引用变量在内存的地址空间,当数据被更改时,不可变类型会重新开辟新的地址空间再对变量赋值,而可变类型则就会在原地址空间进行修改
看下面的例子:

a="abc"
b="abc"
print(id(a),id(b))

输出为:
1539522378640 1539522378640

a="cba"
print(a,b)
print(id(a),id(b))

输出结果:
cba abc
1539572784688 1539522378640
可以看到不可变类型在改变值后,地址空间也改变了
而不可变的类型在重新赋值时会发生下列的情况

a=["abc"]
b=a
print(a,b)
print(id(a),id(b))

结果为
[‘abc’], [‘abc’]
1539571459528 1539571459528

a.append("def")
print(a,b)
print(id(a),id(b))

结果打印为:

[‘abc’, ‘ddd’],[‘abc’, ‘ddd’]
1539571495112 1539571495112
可以看到b的值也改变了,因为在对a更改的时候,a的地址空间并没有变,而b的地址空间还是指向原来的位置的,所以b的值也跟着改变了

在函数作用域的坑:
我们知道函数作用域有全局变量与局部变量
全局变量能够被所有函数共享,但是能不能被函数更改呢,看一下下面的例子:

def fn(n):
    n += 1

num = 1
fn(num)
print(num)

输出结果:
1
函数把num的值改了,但是开辟了新的地址空间,并没有影响到全局num的地址值,所以全局num的值没有改变
再看下面的例子:

def fn(list_test):
    list_test.append("two")

list_a = ["one"]
fn(list_a)
print(list_a)

输出结果:
[‘one’, ‘two’]
这里看到全局变量list_a的值被更改了,因为函数fn在更改list的值时,只是在原来的地址空间上改,所以全局变量list_a还是指向原来的地址空间,即被更改后的值,这点需要特别注意
再看另外一个列子:

class Person:
    name = ["renyi"]
    age = 24


a = Person()
a.name[0] = "mayun"
a.age = 50
# 这时候我们再实例化一个对象b
b = Person()
print(b.name, b.age)

想一想会输出什么?

猜你喜欢

转载自blog.csdn.net/renyiforever/article/details/79881916