Immutable vs Mutable types

前端 未结 16 2020
感情败类
感情败类 2020-11-21 05:51

I\'m confused on what an immutable type is. I know the float object is considered to be immutable, with this type of example from my book:

class         


        
16条回答
  •  执笔经年
    2020-11-21 06:50

    The goal of this answer is to create a single place to find all the good ideas about how to tell if you are dealing with mutating/nonmutating (immutable/mutable), and where possible, what to do about it? There are times when mutation is undesirable and python's behavior in this regard can feel counter-intuitive to coders coming into it from other languages.

    As per a useful post by @mina-gabriel:

    • Books to read that might help: "Data Structures and Algorithms in Python"
    • Excerpt from that book that lists mutable/immutable types: mutable/imutable types image

    Analyzing the above and combining w/ a post by @arrakëën:

    What cannot change unexpectedly?

    • scalars (variable types storing a single value) do not change unexpectedly
      • numeric examples: int(), float(), complex()
    • there are some "mutable sequences":
      • str(), tuple(), frozenset(), bytes()

    What can?

    • list like objects (lists, dictionaries, sets, bytearray())
    • a post on here also says classes and class instances but this may depend on what the class inherits from and/or how its built.

    by "unexpectedly" I mean that programmers from other languages might not expect this behavior (with the exception or Ruby, and maybe a few other "Python like" languages).

    Adding to this discussion:

    This behavior is an advantage when it prevents you from accidentally populating your code with mutliple copies of memory-eating large data structures. But when this is undesirable, how do we get around it?

    With lists, the simple solution is to build a new one like so:

    list2 = list(list1)

    with other structures ... the solution can be trickier. One way is to loop through the elements and add them to a new empty data structure (of the same type).

    functions can mutate the original when you pass in mutable structures. How to tell?

    • There are some tests given on other comments on this thread but then there are comments indicating these tests are not full proof
    • object.function() is a method of the original object but only some of these mutate. If they return nothing, they probably do. One would expect .append() to mutate without testing it given its name. .union() returns the union of set1.union(set2) and does not mutate. When in doubt, the function can be checked for a return value. If return = None, it does not mutate.
    • sorted() might be a workaround in some cases. Since it returns a sorted version of the original, it can allow you to store a non-mutated copy before you start working on the original in other ways. However, this option assumes you don't care about the order of the original elements (if you do, you need to find another way). In contrast .sort() mutates the original (as one might expect).

    Non-standard Approaches (in case helpful): Found this on github published under an MIT license:

    • github repository under: tobgu named: pyrsistent
    • What it is: Python persistent data structure code written to be used in place of core data structures when mutation is undesirable

    For custom classes, @semicolon suggests checking if there is a __hash__ function because mutable objects should generally not have a __hash__() function.

    This is all I have amassed on this topic for now. Other ideas, corrections, etc. are welcome. Thanks.

提交回复
热议问题