Beginner

Variables and Types in Python

Learn about variables, data types, and type conversions in Python with practical Docker-ready examples

Python’s approach to variables is one of the things that makes it so approachable. There are no type declarations, no keywords like int or String — you simply assign a value to a name and Python figures out the rest. This is dynamic typing in action, and it’s a core part of what makes Python feel like “executable pseudocode.”

But don’t mistake dynamic for weak. Python has a strong type system — it won’t silently convert "3" + 5 into 8 the way some languages do. You’ll get a clear TypeError instead. This combination of dynamic and strong typing gives you flexibility without hidden surprises.

In this tutorial you’ll learn how Python handles variable assignment, explore the built-in data types, work with type conversions, and see how to inspect types at runtime.

Variable Assignment

In Python, variables are created the moment you assign a value. There’s no declaration step — the assignment is the declaration. A variable is simply a name that refers to an object in memory.

Create a file named variables.py:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# Variables and Types in Python

# --- Variable Assignment ---
# No type declaration needed - just assign a value
message = "Hello, Python"
count = 42
temperature = 98.6
is_active = True

print("=== Basic Variables ===")
print(f"message = {message}")
print(f"count = {count}")
print(f"temperature = {temperature}")
print(f"is_active = {is_active}")

# Variables can be reassigned to a different type
count = "forty-two"
print(f"\ncount after reassignment = {count}")
print(f"count is now a {type(count).__name__}")

# Multiple assignment
x, y, z = 10, 20, 30
print(f"\nx, y, z = {x}, {y}, {z}")

# Same value assigned to multiple names
a = b = c = 0
print(f"a = b = c = {a}")

# --- Built-in Types ---
print("\n=== Built-in Types ===")

# Integers - arbitrary precision (no overflow)
small = 255
big = 10 ** 20
print(f"small: {small} (type: {type(small).__name__})")
print(f"big: {big} (type: {type(big).__name__})")

# Floats - IEEE 754 double precision
pi = 3.14159
scientific = 2.998e8
print(f"pi: {pi} (type: {type(pi).__name__})")
print(f"scientific: {scientific} (type: {type(scientific).__name__})")

# Strings - immutable sequences of characters
single = 'single quotes'
double = "double quotes"
multi = """triple quotes
span multiple lines"""
print(f"single: {single}")
print(f"double: {double}")
print(f"multi: {multi}")

# Booleans - subclass of int
flag = True
print(f"\nflag: {flag} (type: {type(flag).__name__})")
print(f"True + True = {True + True}")  # Booleans are integers

# NoneType - Python's null
nothing = None
print(f"nothing: {nothing} (type: {type(nothing).__name__})")

# --- Collections Preview ---
print("\n=== Collection Types ===")

# List - ordered, mutable
fruits = ["apple", "banana", "cherry"]
print(f"list: {fruits} (type: {type(fruits).__name__})")

# Tuple - ordered, immutable
point = (3, 4)
print(f"tuple: {point} (type: {type(point).__name__})")

# Dictionary - key-value pairs
person = {"name": "Ada", "age": 36}
print(f"dict: {person} (type: {type(person).__name__})")

# Set - unordered, unique elements
unique = {1, 2, 3, 2, 1}
print(f"set: {unique} (type: {type(unique).__name__})")

# --- Type Conversions ---
print("\n=== Type Conversions ===")

# Explicit conversions using built-in functions
num_str = "42"
num_int = int(num_str)
num_float = float(num_str)
print(f'int("42") = {num_int} (type: {type(num_int).__name__})')
print(f'float("42") = {num_float} (type: {type(num_float).__name__})')

# Number to string
value = 3.14
value_str = str(value)
print(f"str(3.14) = '{value_str}' (type: {type(value_str).__name__})")

# Boolean conversions - "truthy" and "falsy" values
print(f"\nbool(1) = {bool(1)}")
print(f"bool(0) = {bool(0)}")
print(f'bool("") = {bool("")}')
print(f'bool("hello") = {bool("hello")}')
print(f"bool([]) = {bool([])}")
print(f"bool([1]) = {bool([1])}")
print(f"bool(None) = {bool(None)}")

# --- Type Checking ---
print("\n=== Type Checking ===")

# type() returns the exact type
print(f"type(42) = {type(42)}")
print(f"type(3.14) = {type(3.14)}")

# isinstance() checks type hierarchy (preferred for checking)
print(f"isinstance(True, bool) = {isinstance(True, bool)}")
print(f"isinstance(True, int) = {isinstance(True, int)}")  # bool is subclass of int

# --- Constants Convention ---
print("\n=== Constants (Convention) ===")

# Python has no true constants - UPPER_CASE is a convention
MAX_RETRIES = 3
PI = 3.14159265358979
BASE_URL = "https://api.example.com"
print(f"MAX_RETRIES = {MAX_RETRIES}")
print(f"PI = {PI}")
print(f"BASE_URL = {BASE_URL}")
print("(These are conventions - Python won't prevent reassignment)")

Running with Docker

1
2
3
4
5
# Pull the official image
docker pull python:3.13-alpine

# Run the variables example
docker run --rm -v $(pwd):/app -w /app python:3.13-alpine python variables.py

Expected Output

=== Basic Variables ===
message = Hello, Python
count = 42
temperature = 98.6
is_active = True

count after reassignment = forty-two
count is now a str

x, y, z = 10, 20, 30
a = b = c = 0

=== Built-in Types ===
small: 255 (type: int)
big: 100000000000000000000 (type: int)
pi: 3.14159 (type: float)
scientific: 299800000.0 (type: float)
single: single quotes
double: double quotes
multi: triple quotes
span multiple lines
flag: True (type: bool)
True + True = 2
nothing: None (type: NoneType)

=== Collection Types ===
list: ['apple', 'banana', 'cherry'] (type: list)
tuple: (3, 4) (type: tuple)
dict: {'name': 'Ada', 'age': 36} (type: dict)
set: {1, 2, 3} (type: set)

=== Type Conversions ===
int("42") = 42 (type: int)
float("42") = 42.0 (type: float)
str(3.14) = '3.14' (type: str)

bool(1) = True
bool(0) = False
bool("") = False
bool("hello") = True
bool([]) = False
bool([1]) = True
bool(None) = False

=== Type Checking ===
type(42) = <class 'int'>
type(3.14) = <class 'float'>
isinstance(True, bool) = True
isinstance(True, int) = True

=== Constants (Convention) ===
MAX_RETRIES = 3
PI = 3.14159265358979
BASE_URL = https://api.example.com
(These are conventions - Python won't prevent reassignment)

Key Concepts

  • No type declarations — Python variables are created on assignment; the type is determined by the value, not by a keyword
  • Dynamic but strong typing — Variables can be reassigned to any type, but Python won’t implicitly coerce between incompatible types (e.g., "3" + 5 raises a TypeError)
  • Everything is an object — Integers, strings, functions, and even None are objects with types and methods
  • Arbitrary-precision integers — Python integers have no fixed size limit, so you’ll never encounter integer overflow
  • Truthiness — Every object has a boolean value; empty collections, zero, None, and empty strings are falsy; most other values are truthy
  • isinstance() over type() — Use isinstance() for type checking because it respects inheritance (e.g., bool is a subclass of int)
  • Constants are a convention — Python has no const keyword; UPPER_CASE naming signals “don’t reassign this” but the language doesn’t enforce it
  • F-strings for output — The f"..." syntax (Python 3.6+) is the preferred way to embed expressions in strings

Running Today

All examples can be run using Docker:

docker pull python:3.13-alpine
Last updated: