python是一门很特殊的语言,它和C语言不一样,python是"弱类型"的脚本语言,变量在声明的时候并不定义它的类型,而是通过赋值的类型体现出来,所以一般python变量在声明时需要赋初值.
在C语言中, 给变量赋值时,需要先指定数据类型,同时会开辟一块内存区域,用于存储值,
例如 :
int a =0;
当给a赋值: a=5;
这时候内存地址没有变,只是该段内存中的值变了,变成了2。
这时候如果: int b=a;
相当于把值拷贝了一份传递给变量b,b是新开辟的一段内存区域,此时a和b的地址并不相同
而在Python中,“变量”的严格叫法是“名字(name)”,也可以理解为标签,就像每个人的姓名一样,只是标记我们的一个标签。这种方式是和python“万物皆对象”的思想相契合的。
比如:上面这段报错,说的很清楚是name “a” 而不是variable “a" 没有被定义。
再如,上面这段代码,即使是“10”也是被看作是一个int类的对象,a指向这个对象。
在python中,当执行: a = 1
python首先会在分配一段内存空间用来创建int型对象“1”,然后用a指向它;
再执行: a = 2
python 同样会划分内存空间来创建int型对象“2”,然后用 a执行它,这时候,对象“1”就没有办法通过a来找到,不久后将会被内存回收。
再执行:b = a
这里和C语言是完全不一样的,定义b的时候不需要分配内存空间,这样我们既可以通过a来访问2也可以通过b来访问2,此时a和b的地址和值都是一样的。
理解了Python中的变量与赋值后,再来看函数的参数传递,如下所示
这里把形参g传递到函数中,相当于执行 a = g ,这时a和g指向同一个对象,在函数内部给a重新赋值,其实是让a重新指向一个新的对象,并不会对g的值造成影响,同样的函数在C语言中也不会改变函数外面的值,这是因为,形参只是把实参的值接收过来了,二者并不分配在同一地址。
再看看下面这种情况
为什么这次就可以用函数改变外部变量呢?这是因为函数里是对变量指向的对象进行修改,其实,在python内部是类调用自己的方法进行的修改,这时并没有创建新的对象,这时候就能修改外部变量了,就像一个人换了一身衣服,可是它的还是这个人,它的名字仍然表示它。
所以,在python中,函数能不能修改外部变量,主要看这个变量的类型是可修改的还是不可修改的,在Python中strings, tuples, 和 numbers 是不可更改的对象,不能修改。