Python Fundamentals Tutorial: Variables

3. Variables

3.1. Definining

A variable in Python is defined through assignment. There is no concept of declaring a variable outside of that assignment.

>>> ten = 10
>>> ten
10

3.2. Dynamic Typing

In Python, while the value that a variable points to has a type, the variable itself has no strict type in its definition. You can re-use the same variable to point to an object of a different type. It may be helpful to think of variables as "labels" associated with objects.

>>> ten = 10
>>> ten
10
>>> ten = 'ten'
>>> ten
'ten'

3.3. Strong Typing

[Caution]Caution

While Python allows you to be very flexible with your types, you must still be aware of what those types are. Certain operations will require certain types as arguments.

>>> 'Day ' + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  TypeError: cannot concatenate 'str' and 'int' objects

This behavior is different from some other loosely-typed languages. If you were to do the same thing in JavaScript, you would get a different result.

d8> 'Day ' + 1
Day 1

In Python, however, it is possible to change the type of an object through builtin functions.

>>> 'Day ' + str(1)
'Day 1'

This type conversion can be a necessity to get the outcome that you want. For example, to force float division instead of integer division. Without an explicit conversion, the division of two integers will result in a third integer.

>>> 10 / 3
3

By converting one of the operands to a float, Python will perform float division and give you the result you were looking for (at least within floating point precision).

>>> float(10) / 3
3.3333333333333335
>>> 10 / float(3)
3.3333333333333335

You can also force the initial value to be a float by including a decimal point.

>>> 10.0 / 3
3.3333333333333335

Make sure to account for order of operations, though. If you convert the result of integer division, it will be too late to get the precision back.

>>> float(10 / 3)
3.0

3.4. Internals

Each object in Python has three key attributes: a type, a value, and an id. The type and the id can be examined using the type() and id() functions respectively. The id is implementation-dependent, but in most standard Python interpreters represents the location in memory of the object.

>>> a = 1
>>> type(a)
<type 'int'>
>>> id(a)
4298185352
>>> b = 2
>>> type(b)
<type 'int'>
>>> id(b)
4298185328

Multiple instances of the same immutable may be optimized by the interpreter to, in fact, be the same instance with multiple labels. The next example is a continuation of the previous. Notice that by subtracting 1 from b, it’s value becomes the same as a and so does its id. So rather than changing the value at the location to which b points, b itself is changed to point to a location that holds the right value. This location may be the location of an already existing object or it may be a new location. That choice is an optimization made by the interpreter.

>>> b = b - 1
>>> b
1
>>> id(b)
4298185352

Python uses reference counting to track how many of these labels are currently pointing to a particular object. When that count reaches 0, the object is marked for garbage collection after which it may be removed from memory.