Mutable & Immutable
Mutable
  • Changing the value of a mutable variable will not create a new object
  • list, byte array, sets, dict, class instances
  • def changeMutable(v):
    	v[2] = 100 # change 3rd element of v in main program
    	v = [1, 2, 3, 4] # create a new object, not change v in main program
     
    l = list(range(10))
     
    changeMutable(l)
    print(l)# [0, 1, 100, 3, 4, 5, 6, 7, 8, 9]
    			
    Immutable
  • Changing the value of an immutable variable will create a new object with a different id
  • int, float, complex, str, tuples, bytes, frozensets
  • def changeNum(n):
    	n *= 10 # create a new object, not change n in main program
     
    # python create 10 in memory, all three variable points to the same memory
    n = 10;
    n2 = n;
    n3 = 10;
    print(id(n), id(n2), id(n3))
     
    changeNum(n)
    print(n) # 10
     
    # create a string
    s = 'Hello '
    print(id(s)) # 4422154032
    # create a new string object
    s = s+'World!'
    print(id(s)) # 4422194416
    			
    Assignment
    # create an object and assign the reference to l
    l = list(range(10))
     
    # assignment the reference of l to l2
    l2 = l
     
    # create a new object and assign the reference to l3
    l3 = list(range(10)) # mutable variable
     
    # l and l2 point to same object, l3 is a different object
    print(id(l), id(l2), id(l3))
     
    # create an immutable object
    i = (1, 2, 3, 4)
     
    # i and i2 point to same object
    i2 = i
     
    # create a new object
    i3 = (1, 2, 3, 4)
     
    print(id(i), id(i2), id(i3)) # i and i2 are same, and i3 have a different id
    			
    User defined class
    class Vehicle(object):
        """Document String: Define a Vehicle class"""
     
        def __init__(self, brand):
            self._brand = brand;
     
        def __str__(self):
            return self._brand
    
        def __hash__(self):
            return hash(self._brand)
    
        def __eq__(self, other):
            if isinstance(other, self.__class__):
                return self._brand == other._brand
            return NotImplemented
    			
    # mutable object
    def change(v):
        print('Inside function ...')
        print(id(v)) # 4350403216
        v._brand = 'Lincoln'
    
    def main():
        v = Vehicle("Buick")
        print(id(v)) # 4350403216
        print(v) # Buick
    
        change(v)
        print('After call change function ...')
        print(id(v)) # 4350403216
        print(v) # Lincoln
    
    if __name__ == '__main__':
        main()
    			
    # can be used as immutable object if __hash__ and __eq__ are defined
    # use as dictionary key
    
    def main():
        v = Vehicle("Buick")
        container = {v: 100} # use Vehicle instance as key
    
        print(container[Vehicle("Buick")])
    
    if __name__ == '__main__':
        main()
    			
    Resource
  • CODEHABITUDE