Allow me to address the misconceptions in your question one by one.
In Python, I can change the types of values associated with a variable:
>>> x=1
>>> x="abc"
In type theory, types classify expressions, i.e., syntactic objects, i.e., program fragments. From this point of view, Python has exactly one type. Confusingly, what Python calls “types” are what type theory calls classes of a single type.
I was wondering if the following language features have to do with the observation in Python:
- no explicit type annotations,instead of explicit type annotations
Annotations have nothing to do with this. There exist languages, such as ML and Haskell, that allow the programmer to omit most type annotations, yet the type of a variable binding is never allowed to change throughout its scope.
This is not to say that it is impossible to design a programming language in which the type of a variable could change within its scope, but Python is by no means such a language.
- dynamic typing, instead of static typing
What I said above about the meaning of “type” in type theory.
- or reference model of variable, instead of value model of variables?
There is no such thing as “reference model of variable”. A variable always stands for a value. It just so happens that Python has no values other than object references. For example, the Python expression 2 << 1000
does not evaluate to the number $2^{1000}$. It evaluates to an object that represents the number $2^{1000}$. There can be two different objects that represent the same number, as this snippet illustrates:
>>> x = 2 << 1000
>>> y = 2 << 1000
>>> x is y
False
Of course, in mathematics, it makes no sense whatsoever to distinguish between “this $2^{1000}$” and “that $2^{1000}$”. Since Python's int
s do not behave like mathematical integers, Python simply does not have integer values.
Confusingly enough, against established tradition, Python's equality testing operator is called is
rather than ==
.