Dynamic Typing of Python

Python can keep track of objects automatically. Programmer don't need to code declaration statements in python scripts.

Variables, Objects, and References

Variables are created when assigned to objects(it can reference any type of object).

Variables and objects are stored in different parts of memory.

Variables always link to objects and never to other variables, but larger objects may link to other objects.

Objects Are Garbage-Collected

In Python, whenever a name is assigned to a new object, the space held by the prior object is reclaimed if it is not referenced by any other name or object. Python accomplishes this feat by keeping a counter in every object that keeps track of the number of references currently pointing to that object.

Shared References

Multiple names referencing the same object—is usually called a shared reference:

>>> a = 9
>>> b = a       # Now, b points to the same object (integer '9') as a does
>>> a = 'abc'    # a points to a new string object 'abc', but b still points to integer '9'

Shared References and In-Place Changes

Python’s mutable types(including lists, dictionaries, and sets) can be changed in-place.

For instance, an assignment to an offset in a list actually changes the list object itself in
place, rather than generating a brand-new list object:

>>> L1 = [2, 3, 4]
>>> L1[0] = 99        # make a in-place change to L1's first element
>>> L1
[99, 3, 4]

>>> L2 = L1
>>> L1[2] = 100        # make a in-place change to L1's third element
>>> L2
[99, 3, 100]           # L2 changed as well, as L2 still points to same object as L1

If you don’t want such behavior, you can request that Python copy objects instead of making references:

>>> L1 = [2, 3, 4]
>>> L2 = L1[:]   # Make a copy of L1 (or list(L1), copy.copy(L1), etc.)
>>> L1[0] = 24

>>> L1
[24, 3, 4]
>>> L2           # This time, L2 is not changed
[2, 3, 4]

Note that this slicing technique won’t work on dictionaries and sets, because they are not sequences—to copy a dictionary or set, instead use their X.copy() method call.

Also, note that the standard library copy module has a call for copying any object type generically, as well as a call for copying nested object structures—a dictionary with nested lists, for example:

import copy  
X = copy.copy(Y)      # Make top-level "shallow" copy of any object Y  
X = copy.deepcopy(Y)  # Make deep copy of any object Y: copy all nested parts  

Shared References and Equality

>>> L = [1, 2, 3]
>>> M = L         # M and L reference the same object
>>> L == M        # '==' tests L and M have the Same values
>>> L is M        # 'is' tests L and M point to Same objects in memory