我在这里问了一个关于stackoverflow的问题:Python immutable types in function calls
这清楚地表明,只有对不可变对象的引用才传递给函数,因此将元组传递给函数不会导致该对象的完整内存副本。在
但是,根据:http://www.testingreflections.com/node/view/5126
"Some objects, like strings, tuples, and numbers, are immutable. Altering them inside a function/method will create a new instance and the original instance outside the function/method is not changed."
我写了一些测试代码,其中一个不可变的对象被传递给一个函数。正如预期的那样,我可以通过定义为函数头一部分的参数名/引用来修改对象,并且所有的更改只在被调用的函数中保持不变,而不影响函数外部的原始对象。在
所以我的问题是:
新实例是否仅在试图更改/修改传入的对象时创建?我猜如果对象没有改变,只需要引用它。更重要的是,如果python确实在尝试修改时创建了一个副本,那么python如何管理内存?如果写入时拷贝/拷贝为零,还是创建了一个完整的复制对象(整个对象的大小保留在内存中)只在被调用函数中可见?
在Python中,如果不把变量看作包含值的框,而是将其作为附加到对象上的名称,那么您将更加清楚地思考Python中的变量。任何对象都可以附加任意数量的名称;有些名称是函数的局部名称,当函数返回时,这些名称将自动从对象中删除。在
所以当你这样做的时候:
有一个字符串对象,它包含文本“Slartibartfast”,有两个名称可以用来引用它:}。在这两种情况下都可以得到相同的对象;可以使用
name
和{id()
函数来验证这一点。在哪个是字符串的“真实”名称,
name
还是person
?这是个诡计问题。字符串本身没有名称;它只是一个字符串。name
不是一个包含“Slartibartfast”的框,它只是一个引用对象的标识符。person
在Python中具有完全相同的地位;name
不是“更重要的”,仅仅因为它是先赋值的。在现在,假设您“修改”字符串,使其更具荷兰风味:
^{2}$“Modify”用引号括起来,因为您不能修改字符串。由于字符串是不可变的,每个字符串操作都会创建一个新字符串。什么时候发生的?马上。在本例中,将创建新字符串“slaartfast”,并调整名称
person
以引用该字符串。但是,名称name
仍然引用原始字符串,因为您没有告诉它引用其他任何内容。只要至少有一个名字提到它,Python就会保留好的旧的“Slartibartfast”。在在处理函数时,这没有什么不同:
这里我们将字符串“Slartibartfast”指定给全局名称
person
。然后将该字符串传递给函数,在那里它接收附加的本地名称name
。然后通过name
标识符调用字符串的replace()
方法,创建一个新的字符串。然后重新分配标识符name
,以指向新字符串。在函数之外,全局标识符person
仍然引用原始字符串,因为没有任何改变,它指向任何其他字符串。在如果一个对象是不可变的,就没有办法改变它。您可以将一个新对象分配给以前与参数对象关联的名称。为此,您首先需要创建一个新对象。所以是的,你会为一个全新的对象分配空间。在
我不是说python本身。但通常,在不可变的数据结构中,您使用的每个需要更改状态的方法都将返回一个新对象(具有修改后的状态)。旧的将保持不变。在
例如,Java可变列表可以具有:
对应的不可变列表将有一个
^{2}$所以,不可变数据结构一般没有什么特别之处。在任何语言中,您都可以创建不可变的数据结构。一些可变的语言(或者说不可能创建可变的数据结构)。在
有些语言可能提供伪不变的数据结构。它们使一些特殊的数据结构看起来像是不可变的,而实际上它们不是
相关问题 更多 >
编程相关推荐