【每日学一技】【002】Python中传值还是传引用

1. 前言

之前有个困惑,Python 到底传的是值还是引用?不管在哪门编程语言,可能都会遇到类似的问题。Python 中究竟传的是值还是引用呢?本文将主要介绍今日所学:

  1. Python 中的变量和 C 中变量的区别,从而解答 Python 中到底是值传递还是引用传递
  2. Python 中 is 和 == 的区别?

2. C 中的变量 VS Python 中的变量

在静态语言 C 语言中,变量是代表一个地址,它相当于某个内存地址的别名,它可以用来存储指定的数据类型。C 中创建一个变量必须先声明变量的类型,看下面的例子:

# include<stdio.h>

int main(void)
{
    int a = 1024;
    printf("address of a = %p\n", &a);
    printf("value of a = %d\n", a);
    

    a = 520;
    printf("address of a = %p\n", &a);
    printf("value of a = %d\n", a);
    return 0;
}

/*
address of a = 000000000061FE1C
value of a = 1024
address of a = 000000000061FE1C
value of a = 520
/*

可以看到 C 语言中,定义一个变量时必须声明变量的类型,以便于分配相应的内存空间给变量,比如 int a = 1024 ,那么变量 a 就是 int 类型,在 a 的整个生命周期中,a 的类型和内存大小都是固定的,但是内存里面值的大小是可以改变的。如果这时设置 a = 520 ,那么 a 这个内存地址存储的值就会变为 520,但是类型和内存地址不变。

我们在看一下 Python 中的情况:

>>> a = 1024
>>> print(hex(id(a)))
0x232643e01d0
>>> a = 520
>>> print(hex(id(a)))
0x232643e0290

id() 函数是查看对象的内存地址的,可以看到,在 Python 中,变量 a 的地址发生了变化。为什么会这样呢?

因为在 Python 中,变量只是个名字,它相当于 C 语言中的指针,它存储的是对象的内存地址,它指向的内存地址存储的才是真正的对象。所以 Python 中变量是对象的指针!

在 Python 中,不需要声明变量的类型,那么Python 解释器怎么知道分配多少内存呢?答案是靠猜,Python 中创建一个对象的同时你必须先赋值,Python 就是通过你赋的初值来推断这个变量指向的数据类型是什么。所以 Python 是先创建值,这个值对应一个 C 中的结构体,当创建完值后,再将变量指向这个值所在的内存地址。如:a = 1024,在 Python 中会先开辟一块内存,存储 1024,然后将变量 a 指向这块内存地址,换而言之就是让变量 a 成为这块内存地址的指针。当 a = 520 时,在 Python 中会再开辟一块内存,然后将 520 存进去,再将 变量 a 指向 520 所在的内存地址,因为两块内存不同,所以它们地址不同。1024 所在的内存,如果没有变量指向它,那么这块内存将被解释器回收。

这个关系如下图:

在这里插入图片描述

接下来回答一开始的问题,Python 中到底是传值还是传引用?准确的回答是:Python 中变量之间是赋值传递,对象之间是引用传递。我们来看一个例子:

>>> a = 1024
>>> b = a
>>> print(hex(id(a)), hex(id(b)))
0x232643e01f0 0x232643e01f0

可以看到,a 和 b 指向的是同一个内存地址,或者说同一个对象。具体的行为就是 a = 1024,Python 会先开辟一块内存,存储1024,然后将这块内存的地址,即指针赋值给变量 a,所以变量 a 里面实际上存的就是 1024 的内存地址,当 b = a 时,会被 a 存储的内存地址赋值(拷贝)给 变量 b ,这样 变量 b 也指向了 1024 所在的内存地址。通俗点说,就相当于 a 和 b 两个标签都贴在了对象 1024 上。如下图所示:

在这里插入图片描述

另外还有一点需要注意,id(a) 获得的不是变量 a 的地址,而是变量 a 指向的对象的内存地址,也就是 变量 a 的值!实际上,变量 a 也是有地址的,只是在 Python 中不可见,Python 解释器只让你看到对象的地址。

3. is VS ==

弄明白Python中的变量之后,我们看常见的面试题, is 和 == 的区别?

答案:

is 比较的是两个对象的内存地址,== 比较的是两个对象的值是否相同。

编程实践中我们通常用的是 ==,通常我们只有在比较 None 时用 is。

>>> a, b = 2048, 2048
>>> print(a is b)
False
>>> print(a == b)
True
>>> if a is None:  # 推荐
...     print("good")
...
>>> if a == None:  # 不推荐
...     print("bad")
...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值