What is the language feature which allows a variable to be associated with values of different types?

In Python, I can change the types of values associated with a variable:

>>> x=1
>>> x="abc"


In C, I can't do the same.

What is the name of the feature that allows Python to behave so, while not C?

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
• dynamic typing, instead of static typing
• or reference model of variable, instead of value model of variables?

Thanks.

• The name of the feature is “dynamic typing”. :-) – beroal Feb 27 '20 at 15:50

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 ints 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 ==.