Python Variables & Data Types
In languages like C or Java, a variable is a named memory box with a fixed byte width allocated directly on the call stack. In Python, variables are reference pointers (names/labels) bound to heap memory objects.
Every object in CPython is represented by a C struct called PyObject, which encapsulates three fundamental pieces of metadata:
- Type (
ob_type): Tells Python what operations are permitted on this object. - Reference Count (
ob_refcnt): Tracks how many variables currently point to this object (used for automatic Garbage Collection). - Value: The actual binary data payload stored in memory.
# Creating variables of the 4 core primitive data types:
student_name = "Alex" # str (Text string)
age = 20 # int (Whole integer number)
account_balance = 1450.75 # float (Decimal number)
is_enrolled = True # bool (Boolean True or False)
# Print each variable and inspect its data type:
print("Student Name:", student_name, "| Data Type:", type(student_name).__name__)
print("Age:", age, "| Data Type:", type(age).__name__)
print("Balance: Rs.", account_balance, "| Data Type:", type(account_balance).__name__)
print("Is Enrolled:", is_enrolled, "| Data Type:", type(is_enrolled).__name__)
str: Text string enclosed in quotes.int: Whole numbers with unlimited precision.float: Numbers with decimal points (64-bit IEEE 754 precision).bool: Binary logic flags (TrueorFalse).
Python is dynamically typed. This means you do not declare variable types, and a variable can point to an integer at one moment, and later be rebound to a string or list without compile errors:
# A single variable 'data' rebound to different data types over time:
data = 42
print("1. Value:", data, "| Type:", type(data))
data = "Now I am a text string!"
print("2. Value:", data, "| Type:", type(data))
data = [10, 20, 30]
print("3. Value:", data, "| Type:", type(data))
In Python, objects have types, variables do not! A variable is simply an identifier attached to an object in memory.
Every object in Python has a unique memory address returned by id(obj):
==(Value Equality): Checks if two objects hold identical contents (calls__eq__()).is(Identity Equality): Checks if two variables point to the exact same memory address (id(a) == id(b)).
# Two separate list objects created with identical values:
list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1 # list3 points to the EXACT same list as list1!
print("list1 == list2 (Values match?):", list1 == list2) # True
print("list1 is list2 (Same memory?):", list1 is list2) # False (Two separate lists!)
print("list1 is list3 (Same pointer?):", list1 is list3) # True
print("\nMemory Address list1:", id(list1))
print("Memory Address list2:", id(list2))
print("Memory Address list3:", id(list3))
Always use == for comparing data values (numbers, strings, lists). Use is strictly when comparing singleton constants like None, True, or False.
In C/Java, swapping two variables requires a temporary variable (temp = a; a = b; b = temp;). In Python, you swap variables in a single clean line using tuple packing and unpacking:
x = 10
y = 20
print(f"Before swap: x = {x}, y = {y}")
# One-line swap via tuple packing and unpacking:
x, y = y, x
print(f"After swap: x = {x}, y = {y}")
The right side y, x creates a temporary tuple (20, 10) in memory, which is immediately unpacked into the variable names x and y on the left side simultaneously.
Never name variables list, str, int, dict, id, or sum (e.g. list = [1, 2, 3]). Doing so overrides Pythonβs built-in constructors in the local namespace, crashing subsequent calls like list("abc") with a TypeError: 'list' object is not callable.
Declare variables for your favorite book name, its price, and release year. Print each variable along with its type using type().
book_title = "Python for Beginners"
book_price = 29.99
release_year = 2026
print("Book:", book_title, "| Type:", type(book_title).__name__)
print("Price:", book_price, "| Type:", type(book_price).__name__)
print("Year:", release_year, "| Type:", type(release_year).__name__)
Q What is Dynamic Typing vs Static Typing?
In static typing (C, C++, Java), variable types are checked and fixed at compile time. In dynamic typing (Python, JavaScript, Ruby), types are bound to memory objects at runtime, allowing variables to be rebound to different types freely.
Q Why does id(256) == id(256) evaluate to True, but id(1000) == id(1000) might differ?
CPython pre-allocates and caches small integers between -5 and 256 in an internal global array for instant reuse. Numbers outside this range are created as fresh heap objects on demand.
Q What is Duck Typing in Python?
Duck typing is a programming philosophy: "If it walks like a duck and quacks like a duck, it's a duck." Python does not check the explicit inheritance hierarchy of an object, but rather whether the object possesses the required methods and attributes.