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