开发者

Python immutable object from within function

I asked a previous question on stackoverflow here: Python immutable types in function calls

which made it clear that only references to immutable objects are passed to functions, and so passing a tuple to a function does not result in a full memory copy of that object.

However, according to: 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."

I wrote some test code, where an immutable object is passed to a function. As expected, I can modify the object via the parameter-name/reference defined as part of the function header, and all changes only persist within the called function, leaving the original object outside of the function untouched.

So my question is:

Is the new instance created only when an attempt is made to alter/modify the object passed in? I'm guessing that if the object is not changed, a reference to it is all that is required. More importantly, if it does create a copy upon开发者_高级运维 attempted modification, how does python manage the memory? With a zero-copy/copy-on-write, or does it create a complete replicated object (with the whole object's size reserved in memory) visible only within the called function?


You will think a lot more clearly about variables in Python if you think of them not as boxes that contain values, but names that are attached to objects. Any object can have any number of names attached to it; some of the names are local to functions and will be taken off the object automatically when the function returns.

So when you do something like this:

name = "Slartibartfast"
person = name

There is a string object, which contains the text "Slartibartfast", and there are two names by which it can be referred: name and person. You get the same object in both cases; you can verify this with the id() function.

Which is the "real" name of the string, name or person? This is a trick question. The string does not inherently have a name; it is just a string. name is not a box that contains "Slartibartfast", it is just an identifier that refers to the object. person has exactly the same standing in Python; name is not "more important" just because it was assigned first.

NOTE: Some objects, such as functions and classes, have a __name__ attribute that holds the name that was used to declare it in the def or class statement. This is the object's "real name" if it can be said to have one. However, you can still reference it through any number of assigned names.

Now, suppose you "modify" the string to give it a bit more of a Dutch flavor:

person = person.replace("art", "aart")

"Modify" is in quotes because you can't modify a string. Since a string is immutable, every string operation creates a new string. When does it happen? Immediately. In this case, the new string "Slaartibaartfast" is created and the name person is adjusted to refer to that. However, the name name still refers to the original string, because you haven't told it to refer to anything else. As long as at least one name refers to it, Python will keep good old "Slartibartfast" around.

This is no different when dealing with a function:

def dutchnametag(name):
    name = name.replace("art", "aart")
    print "HELLO! My Dutch name is", name

person = "Slartibartfast"
dutchnametag(person)

Here we assign the string "Slartibartfast" to the global name person. We then pass that string to our function, where it receives the additional local name name. The string's replace() method is then called through the name identifier, creating a new string. The identifier name is then reassigned to point to the new string. Outside the function, the global identifier person still refers to the original string, because nothing has changed it to point to anything else.


I'm not speaking about python per se. But generally, in immutable data structures, every method that you use that needs to change state will return a new object (with the modified state). The old one will remain the same.

For example, a Java mutable list could have:

void addItem(Object item) { ... }

the correspondent immutable List would have a method in the lines of

List addItem(Object item) { ... }

So, there is generally nothing special about immutable data structures. In any language you may create immutable data structures. But some languages make it hard or impossible to create mutable data structures (generally, functional languages).

Some languages may provide pseudo-immutable data structures. They make some special data structures look like immutable to the coder, while indeed they aren't.


If an object is immutable there is no way to change it. You could assign a new object to the name formerly associated with the argument object. To do this you first need to make a new object. So yes, you would allocate space for a complete new object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜