The immutable object in python

后端 未结 4 401
旧时难觅i
旧时难觅i 2020-12-21 23:28

I see a article about the immutable object.

It says when:
variable = immutable
As assign the immutable to a variable.

for example

相关标签:
4条回答
  • 2020-12-21 23:42

    Because interning has already been explained, I'll only address the mutable/immutable stuff:

    As assign the immutable to a variable.

    When talking about what is actually happening, I wouldn't choose this wording.

    We have objects (stuff that lives in memory) and means to access those objects: names (or variables), these are "bound" to an object in reference. (You could say the point to the objects)

    The names/variables are independent of each other, they can happen to be bound to the same object, or to different ones. Relocating one such variable doesn't affect any others.

    There is no such thing as passing by value or passing by reference. In Python, you always pass/assign "by object". When assigning or passing a variable to a function, Python never creates a copy, it always passes/assigns the very same object you already have.

    Now, when you try to modify an immutable object, what happens? As already said, the object is immutable, so what happens instead is the following: Python creates a modified copy.

    As for your example:

    a = 10
    b = a
    a =20
    print (b) #b still is 10
    

    This is not related to mutability. On the first line, you bind the int object with the value 10 to the name a. On the second line, you bind the object referred to by a to the name b.

    On the third line, you bind the int object with the value 20 to the name a, that does not change what the name b is bound to!

    It says in this case a refers to a copy of b, not reference to b. If b is mutable, the a wiil be a reference to b

    As already mentioned before, there is no such thing as references in Python. Names in Python are bound to objects. Different names (or variables) can be bound to the very same object, but there is no connection between the different names themselves. When you modify things, you modify objects, that's why all other names that are bound to that object "see the changes", well they're bound to the same object that you've modified, right?

    If you bind a name to a different object, that's just what happens. There's no magic done to the other names, they stay just the way they are.

    As for the example with lists:

    In [1]: smalllist = [0, 1, 2] 
    In [2]: biglist = [smalllist]    
    In [3]: biglist
    Out[3]: [[0, 1, 2]] 
    

    Instead of In[1] and In[2], I might have written:

    In [1]: biglist = [[0, 1, 2]]
    In [2]: smalllist = biglist[0]
    

    This is equivalent.

    The important thing to see here, is that biglist is a list with one item. This one item is, of course, an object. The fact that it is a list does not conjure up some magic, it's just a simple object that happens to be a list, that we have attached to the name smalllist.

    So, accessing biglist[i] is exactly the same as accessing smalllist, because they are the same object. We never made a copy, we passed the object.

    In [14]: smalllist is biglist[0]
    Out[14]: True
    

    Because lists are mutable, we can change smallist, and see the change reflected in biglist. Why? Because we actually modified the object referred to by smallist. We still have the same object (apart from the fact that it's changed). But biglist will "see" that change because as its first item, it references that very same object.

    In [4]: smalllist[0] = 3
    In [5]: biglist
    Out[5]: [[3, 1, 2]]
    

    The same is true when we "double" the list:

    In [11]: biglist *= 2
    In [12]: biglist
    Out[12]: [[0, 1, 2], [0, 1, 2]]
    

    What happens is this: We have a list: [object1, object2, object3] (this is a general example) What we get is: [object1, object2, object3, object1, object2, object3]: It will just insert (i.e. modify "biglist") all of the items at the end of the list. Again, we insert objects, we do not magically create copies.

    So when we now change an item inside the first item of biglist:

    In [20]: biglist[0][0]=3
    In [21]: biglist
    Out[21]: [[3, 1, 2], [3, 1, 2]]
    

    We could also just have changed smalllist, because for all intents and purposes, biglist could be represented as: [smalllist, smalllist] -- it contains the very same object twice.

    0 讨论(0)
  • 2020-12-21 23:55

    have a read of this... http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables

    0 讨论(0)
  • 2020-12-21 23:56

    While that article may be correct for some languages, it's wrong for Python.

    When you do any normal assignment in Python:

    some_name = some_name_or_object
    

    You aren't making a copy of anything. You're just pointing the name at the object on the right side of the assignment.

    Mutability is irrelevant.

    More specifically, the reason:

    a = 10
    b = 10
    a is b
    

    is True, is that 10 is interned -- meaning Python keeps one 10 in memory, and anything that is set to 10 points to that same 10.

    If you do

    a = object()
    b = object()
    a is b
    

    You'll get False, but

    a = object()
    b = a
    a is b
    

    will still be True.

    0 讨论(0)
  • 2020-12-22 00:07

    "Simple" immutable literals (and in particular, integers between -1 and 255) are interned, which means that even when bound to different names, they will still be the same object.

    >>> a = 'foo'
    >>> b = 'foo'
    >>> a is b
    True
    
    0 讨论(0)
提交回复
热议问题