鱼C论坛

 找回密码
 立即注册
查看: 2046|回复: 5

python中关于变量与对象关系的疑惑

[复制链接]
发表于 2023-9-23 20:55:21 | 显示全部楼层 |阅读模式
60鱼币
在python中使用赋值、乘法、拷贝、切片、加法、对象的增删改等操作修改一个变量所对应的对象的时候,什么情况下会在内存中创建一个新的对象,然后将变量与新创建的对象挂钩,什么时候仅仅是消除变量与一个对象的挂钩,并建立变量与另一个对象的挂钩,而并没有创建出一个新的对象?比如在进行诸如a=[1,2,3]  b=[1,2,3]此类的操作的时候,究竟是在内存中创建了两个相同的列表,然后分别与a和b挂钩,还是只创建了一个列表,a和b均与其挂钩?(当然本操作的结果可以用id函数轻松得到),但是这种变量与对象之间关系的底层逻辑究竟是什么?有什么总结的规律吗?

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-23 20:55:42 | 显示全部楼层
在 Python 中,变量与对象之间的关系是基于引用的。当一个对象被创建时,Python 会为其分配一块内存空间,并返回该内存地址的引用。变量则是对这个引用的名称(或者说是标签),通过这个名称可以访问该对象。所以,当我们使用变量对对象进行修改时,实际上是修改了指向该对象的引用,而不是修改了对象本身。

在 Python 中,对于简单的数值型、字符串、元组等不可变类型的对象,修改这些对象时必须重新创建一个对象,并将原来的引用指向新的对象,因为不可变对象的内容无法修改。而对于列表、字典等可变对象,则可以直接在原有对象上进行修改,而不需要重新创建一个新的对象。下面以列表为例进行说明:

1. 对于 a = [1, 2, 3] 和 b = a 这类情况,由于 a 和 b 指向同一块内存空间,因此修改其中一个变量对应的列表对象,另一个变量所对应的列表对象也会被修改。例如:a[0] = 4,那么 b[0] 也会变成 4。

2. 对于 a = [1, 2, 3] 和 b = [1, 2, 3] 这种情况,Python 会在内存中创建两个相同的列表对象,并将 a 和 b 两个变量分别指向这两个对象。因此当对其中一个变量的列表对象进行修改时,不会影响到另一个列表对象。

3. 当使用 b = a.copy() 或者 b = a[:] 来进行浅拷贝时,Python 会创建一个新的列表对象,并复制原列表中的元素到这个新列表中,然后将变量 b 指向这个新对象。这样,当对变量 b 对应的列表对象进行修改时,不会影响到变量 a 对应的列表对象。

4. 当使用深拷贝 b = copy.deepcopy(a) 时,则会完全复制原始对象及其嵌套的所有对象,并将其存储在一个新的内存地址中,然后将变量 b 指向这个新对象。这样,当对变量 b 对应的对象进行修改时,不会影响到变量 a 对应的对象。

综上所述,在 Python 中,修改一个变量所对应的对象是否需要创建新的对象,主要取决于该对象的可变性(是否可以被修改)和修改方式。可变对象可以直接在原有对象上进行修改而无需创建新的对象,而不可变对象则必须创建新的对象进行修改。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-23 20:56:08 | 显示全部楼层
关于变量与对象的关系

在Python中,变量与对象之间的关系是通过引用来实现的。当你给一个变量赋值时,它实际上是指向了一个对象在内存中的地址。对象可以是数字、字符串、列表、字典等。

下面我们来逐个讨论不同操作情况下的变量与对象关系。

1. 赋值操作:当你执行赋值操作时,变量会指向一个已存在的对象或者新创建的对象。如果新创建了一个对象,那么该对象会被分配一块内存,并且变量会指向这个新对象的地址。如果是指向已存在的对象,则直接让变量指向该对象的地址。
a = [1, 2, 3]  # 创建了一个列表对象,变量a指向该对象的地址b = a  # 变量b指向与变量a相同的对象地址
在这个例子中,变量 ab 都指向了同一个列表对象的地址,所以它们指向同一个对象。

2. 拷贝操作:Python中有两种拷贝方式,浅拷贝和深拷贝。

   - 浅拷贝:通过复制引用,创建一个新的变量指向原始对象(共享内存地址),也就是创建了一个新的引用指向原始对象。如果改变原始对象,新的引用也会受到影响。

   - 深拷贝:完全复制对象和对象中包含的所有子对象,创建全新的对象,并且不共享内存地址。如果改变原始对象,新的对象不会受到影响。
import copya = [1, 2, 3]b = copy.copy(a)  # 浅拷贝,变量b指向与变量a相同的列表对象地址c = copy.deepcopy(a)  # 深拷贝,变量c指向了一个新创建的列表对象的地址
在这个例子中,变量 abc 分别指向了不同的对象地址。

3. 修改操作:当你对一个对象进行修改时,不会创建一个新的对象,而是直接修改原始对象。
a = [1, 2, 3]a.append(4)  # 在原始列表对象上添加一个元素,没有创建新对象
在这个例子中,变量 a 所指向的列表对象被修改,但没有创建新的对象。

总结一下规律:

- 赋值操作:如果是赋值给已存在的对象,变量指向该对象;如果是赋值给新创建的对象,会创建一个新对象并让变量指向它。
- 拷贝操作:浅拷贝通过复制引用,深拷贝创建一个全新的对象。
- 修改操作:直接作用在原始对象上,不会创建新的对象。

希望以上解答对你有帮助!

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-24 19:47:34 | 显示全部楼层
在Python中,变量与对象之间的关系涉及到对象的可变性和赋值方式。理解这些概念可以帮助你了解何时会创建新对象,何时会共享对象。

1. **可变对象 vs. 不可变对象**:
   - **不可变对象**,如数字、字符串和元组,一旦创建,就不能被修改。当你对不可变对象执行操作时,通常会创建新的对象,而不是修改原有对象。
   - **可变对象**,如列表和字典,可以在其生命周期内修改。操作可变对象时,通常不会创建新对象,除非你明确要求。

2. **赋值**:
   - 赋值操作将一个变量与一个对象关联起来,而不是创建新对象。例如:`a = [1, 2, 3]`,会创建一个新列表对象,并将变量 `a` 指向这个列表。

3. **拷贝**:
   - 拷贝操作通常用于创建对象的副本。有两种主要的拷贝方式:
     - **浅拷贝**:复制容器对象本身,但不复制容器内的元素。可以使用 `copy()` 方法或切片操作来创建浅拷贝。例如:`b = a.copy()` 或 `b = a[:]`。这将创建一个新对象 `b`,但其内部元素与 `a` 中的元素仍然是相同的对象引用。
     - **深拷贝**:复制容器对象及其所有嵌套的元素。可以使用 `copy` 模块的 `deepcopy()` 函数来创建深拷贝。例如:`import copy; b = copy.deepcopy(a)`。这将创建一个完全独立的新对象 `b`,其中的元素是原始对象的副本。

4. **切片**:
   - 切片操作通常用于创建可变对象的副本。例如,`b = a[:]` 会创建列表 `a` 的一个浅拷贝,因此 `b` 和 `a` 不共享相同的列表对象。

5. **加法**:
   - 对于可变对象(如列表和字典),可以使用加法来合并两个对象。例如,`a = [1, 2]` 和 `b = [3, 4]`,`c = a + b` 会创建一个新的列表对象 `c`,其中包含 `a` 和 `b` 的元素。这不会修改原始列表 `a` 和 `b`。

6. **对象的增删改**:
   - 当你对可变对象进行增删改操作时,通常不会创建新对象,而是直接修改原始对象。例如,`a.append(4)` 会将元素 `4` 添加到列表 `a` 中,而不会创建新列表。

总结规律:
- 对于不可变对象,一般情况下,操作会创建新对象。
- 对于可变对象,赋值、切片(浅拷贝)、加法等操作不会创建新对象,而是在原始对象上进行操作。
- 如果需要明确创建对象的副本,可以使用浅拷贝或深拷贝操作。
- 使用 `id()` 函数可以帮助你确定变量是否引用相同的对象。

在你提到的例子中,`a` 和 `b` 是两个不同的列表对象,因为赋值操作创建了新对象。如果你希望它们共享同一个对象,可以使用浅拷贝或者将一个变量设置为另一个的引用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-24 23:32:24 | 显示全部楼层
本帖最后由 阿奇_o 于 2023-9-24 23:40 编辑

我基本上将“变量”看做是“名字”,just another name 而已。。

另外,关键通常是 随时要能区分开:这是 名字,还是 对象? 我这样做 其实是 在操作什么

—— 赋值操作,显然是将 看得见的名字看不见的对象  绑在一起(又曰“引用”,即建立引用关系),然后方便 “以名唤之”。。

—— 其他操作(增删改查)呢? 是在操作 对象的名字name ?对象的值value ?  对象的id/内存地址?

—— 这个对象,是位于 容器对象(列表/字典/元组/集合/实例/类/模块/...)里的第几层? 这个对象是否允许修改?修改什么?

—— mutable可变的,到底是指什么可变? immutable不可变,又是指什么不可变?


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-9-27 07:44:28 | 显示全部楼层
同样是GPT,2楼的明显比其他楼的质量高,至少没有把基本问题说错,3楼4楼回答的内容都存在错误,GPT不够好呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-14 14:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表