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 thedef
orclass
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.
精彩评论