I was trying to figure out exactly how Python 3 (using CPython as an interpreter) executes its program. I found out that the steps are:
Compilation of Python so
It could be useful for your understanding to avoid thinking of "variables" in Python. Compared to statically typed languages that have to associate a type with a variable, a class member, or a function argument, Python only deals with "labels" or names for objects.
So in the snippet,
a = "a string"
a = 5 # a number
a = MyClass() # an object of type MyClass
the label a
never has a type. It is just a name that points to different objects at different times (very similarly, in fact, to "pointers" in other languages). The objects on the other hand (the string, the number) always have a type. This nature of this type could change, as you can dynamically change the definition of a class, but it will always be determined, i.e. known by the language interpreter.
So to answer the question: Python never determines the type of a variable (label/name), it only uses it to refer to an object and that object has a type.