>>> d
{1: 1, 2: 2, 3: 3}
>>> lst = [d, d]
>>> c=lst[0]
>>> c[1]=5
>>> lst
[{1: 5, 2: 2, 3: 3}, {1: 5, 2: 2, 3: 3}]
Run Code Online (Sandbox Code Playgroud)
何时lst = [d, d],是lst[0]和lsg[1]都引用内存块d,而不是创建两个内存块并分别复制d它们的内容?
什么时候c=lst[0],c只是引用占用的内存lst[0],而不是创建一个新的内存块并从中复制内容lst[0]?
在Python中,何时创建引用以指向现有内存块,何时分配新内存块然后复制?
Python的这种语言特性与C不同.这种语言特征的名称是什么?
谢谢.
所有变量(以及其他容器,如字典,列表和对象属性)都包含对对象的引用.在实例化对象时发生内存分配.简单赋值始终创建对现有对象的另一个引用.例如,如果您有:
a = [1, 2, 3]
b = a
Run Code Online (Sandbox Code Playgroud)
然后b和a指向同一个对象,一个列表.您可以使用is运算符验证:
print(b is a) # True
Run Code Online (Sandbox Code Playgroud)
如果更改a,则b也会更改,因为它们是同一对象的两个名称.
a.append(4)
print(b[3] == 4) # True
print(b[3] is a[3]) # also True
Run Code Online (Sandbox Code Playgroud)
如果要创建副本,则必须明确地执行此操作.以下是一些执行此操作的方法:
b = a[:].b = list(a).创建自己的类时,如果需要复制功能,这是一个很好的方法.copy模块具有可用于复制对象(浅或深)的方法.对于不可变类型,例如字符串,数字和元组,永远不需要复制.您只能通过引用不同的值来"更改"这些类型的值.
描述这个的最好方法可能是"一切都是对象".在C中,像整数这样的"原始"类型与数组的处理方式不同.在Python中,它们不是:所有值都存储为对象的引用 - 甚至是整数.
简而言之; Python 是按引用传递的。对象是在其构造时创建并分配内存的。引用对象不会分配更多内存,除非您创建新对象或扩展现有对象 ( list.append())
这篇文章Is Python pass-by-reference or pass-by-value很好地介绍了它。
作为旁注;如果您担心 Python 等管理编程语言中的内存分配方式,那么您可能使用了错误的语言和/或过早优化。此外,Python 中的内存管理方式是特定于实现的,因为 Python 有许多实现;CPython(您可能正在使用的);Jython、IronPython、PyPy、MicroPython 等
| 归档时间: |
|
| 查看次数: |
309 次 |
| 最近记录: |