Python Variables and Data Types Explained (2026)
🐍 Python Cluster — 1 of 15 · Fundamentals

Python Variables and Data Types Explained (2026)

Python variables and data types look simple right up until they aren't. A beginner writes a running-total calculator: total = 0, then total += input("Enter amount: ") in a loop. Enter 10, then 15 — instead of 25, the program prints 1015. No error. No crash. Just the wrong answer, because input() always returns a string, and + between two strings concatenates instead of adding. This guide covers exactly what's happening there, plus every core type, mutability, and safe type conversion.

by Khalid Hussain Published Aug 4, 2026 🕐 12 min read

Quick Answer: Python Variables and Data Types

▶ Direct Answer — Python Variables and Data Types

A Python variable is a name bound to a value — no type declaration needed, since Python figures out the type automatically from the value itself (dynamic typing). The core built-in data types are int, float, str, bool, and None. Some types are mutable (can change in place, like a list) and some are immutable (cannot, like a string or integer). Most beginner bugs in this area come from one thing: assuming Python will convert between types automatically when it won't.

0
type declarations needed — Python infers types automatically
Dynamic typing
5
core built-in types: int, float, str, bool, None
Everything else builds on these
str
what input() always returns, regardless of what's typed
The source of the 1015 bug

The 1015 Bug

A beginner builds a simple running-total calculator. The logic looks completely reasonable: start at zero, ask the user for an amount, add it to the total, repeat.

pythonTHE_BUG.PY
total = 0
for _ in range(2):
    amount = input("Enter amount: ")
    total += amount

print(total)  # enter 10, then 15 — expects 25, prints 1015

No crash, no error message — just a silently wrong answer. The cause: input() always returns a string, no matter what the user types. "10" + "15" doesn't add two numbers — it concatenates two pieces of text, producing "1015". Python never assumed you meant addition, because as far as the type system is concerned, you asked it to combine text.

The fix is one line — amount = int(input("Enter amount: ")) — but understanding why the bug happened at all requires actually understanding how Python's types work, which is exactly what the rest of this article covers.

What a Variable Actually Is

A Python variable is a name that points to a value in memory — there's no separate "declare the type, then assign a value" step like in some other languages.

pythonVARIABLES.PY
age = 28
name = "Maria"
is_active = True

age = "twenty-eight"  # completely legal — age now points to a string instead

That last line is legal because Python uses dynamic typing: a variable name doesn't carry a fixed type — the value it currently points to does. Reassigning age to a string doesn't error; the name just points somewhere else now. This flexibility is convenient, but it's also exactly why type-related bugs like the one above don't get caught until the program actually runs.

Naming rules

Variable names must start with a letter or underscore, can contain letters, numbers, and underscores, and are case-sensitive — total and Total are different variables. Convention (PEP 8) favors lowercase with underscores: order_total, not orderTotal.

The Core Data Types

Five built-in types cover the overwhelming majority of everyday Python code.

pythonCORE_TYPES.PY
whole_number = 42              # int
decimal_number = 19.99          # float
text = "data science"          # str
flag = True                      # bool
nothing = None                    # NoneType

print(type(whole_number))  # <class 'int'>
  • int — whole numbers, positive or negative, no size limit beyond available memory.
  • float — decimal numbers, stored as floating-point approximations (the same rounding caveats covered for SQL's DECIMAL vs FLOAT apply here too).
  • str — text, always wrapped in quotes, immutable once created.
  • bool — exactly two values, True or False, technically a subtype of int (True == 1).
  • None — represents the deliberate absence of a value, not zero and not an empty string.

Mutable vs Immutable: Why It Matters Later

Every Python value is either mutable (changeable in place) or immutable (never changed, only replaced) — a distinction that becomes critical the moment lists and dictionaries enter the picture in the next article.

ImmutableMutable
int, floatlist
strdict
tupleset
bool
pythonIMMUTABLE_PROOF.PY
name = "maria"
upper_name = name.upper()

print(name)        # still "maria" — the original string never changed
print(upper_name)  # "MARIA" — a brand-new string was created instead

name.upper() looks like it modifies the string in place — it doesn't. Strings are immutable, so every "modifying" string method actually returns a new string, leaving the original untouched. This is why forgetting to capture the return value (name.upper() alone, with no assignment) silently does nothing useful.

Type Conversion: The Actual Fix

Python never silently converts between fundamentally different types in an operation — you have to do it explicitly, using a small set of built-in conversion functions.

pythonTYPE_CONVERSION.PY
amount_text = input("Enter amount: ")
amount = int(amount_text)     # str -> int, the actual fix for the 1015 bug

price = float("19.99")     # str -> float
label = str(42)             # int -> str, for combining with text
⚠ Conversion can fail

int("abc") raises a ValueError — not every string is a valid number. Any time a conversion runs on real user input rather than a value you control, wrap it in a try/except block instead of assuming it will always succeed.

type() vs isinstance()

Both answer "what type is this," but they're not interchangeable inside real conditional logic.

pythonTYPE_VS_ISINSTANCE.PY
value = 42

# quick debugging check
print(type(value))                 # <class 'int'>

# the safer choice inside actual logic
if isinstance(value, int):
    print("it's an int")

isinstance() correctly handles subclasses — since bool is technically a subclass of int, isinstance(True, int) returns True, which is usually what you actually want. A direct type(value) == int comparison misses that relationship entirely. Use type() for quick, throwaway debugging; use isinstance() anywhere a real decision depends on the check.

f-strings: The Modern Way to Combine Types

Rather than manually converting every value to a string before combining it with text, an f-string handles the conversion automatically, inline.

pythonFSTRINGS.PY
total = 25
name = "Maria"

# old way: manual str() conversion required
message = name + " spent $" + str(total)

# f-string: handles the conversion for you
message = f"{name} spent ${total}"

print(message)  # Maria spent $25

Inside an f-string's {}, any value — int, float, bool, even the result of a function call — gets converted to its string representation automatically. This is the standard, current way to build strings from mixed types in Python, and it sidesteps the entire class of "can't concatenate str and int" errors when the goal is display, not math.

Mistakes That Give Away a Beginner

  • Assuming input() returns a number. The exact trap from this article's opening — it always returns a string, every time, with no exceptions.
  • Calling a string method and expecting it to modify the original. Strings are immutable — capture the return value, or nothing changes.
  • Converting user input without handling failure. int() on invalid text raises a ValueError — wrap it in try/except for anything not fully controlled.
  • Using type() for a real conditional check instead of isinstance(), and missing subclass relationships as a result.
  • Confusing None with 0, False, or an empty string. They're all "falsy" in a boolean context, but None specifically means "no value was set," not "the value is zero."

Practice: Fix These Three Yourself

Try each of these before moving to the next article:

1

Fix the running total

Rewrite the 1015-bug calculator so it correctly adds numbers instead of concatenating strings.

2

Check a type safely

Write a function that accepts any value and uses isinstance() to print whether it's a number (int or float).

3

Build a message with an f-string

Given a name (str), age (int), and is_member (bool), build one sentence combining all three using an f-string.

Frequently Asked Questions

What are the basic data types in Python?

The core built-in types are int (whole numbers), float (decimal numbers), str (text), bool (True or False), and NoneType (the absence of a value, written as None). More complex types like list, tuple, dict, and set are built from these basic ones.

Do I need to declare a variable's type in Python?

No. Python uses dynamic typing, meaning a variable's type is determined automatically from the value assigned to it, and the same variable name can be reassigned to a different type later in the program without declaring anything upfront.

What is the difference between mutable and immutable data types in Python?

A mutable type can be changed in place after creation, like a list or dictionary. An immutable type cannot be changed after creation; any operation that looks like it modifies a string, integer, or tuple actually creates a new object instead. This affects how variables behave when copied or passed to functions.

Why does adding a string and a number cause an error in Python?

Python's + operator is type-specific: between two numbers it adds, but between two strings it concatenates, and it refuses to mix a string with a number directly, raising a TypeError. Values from input() are always strings, which is why this error commonly appears when combining user input with a number without converting it first.

What is the difference between type() and isinstance() in Python?

type() returns a value's exact type and is common for quick debugging. isinstance() checks whether a value is an instance of a type or any of its subclasses, and is the recommended choice inside actual conditional logic because it correctly handles inheritance, which a direct type() comparison does not.

How do you convert a string to an integer in Python?

Use int() to convert a string containing whole digits to an integer, for example int('42') returns 42. Converting a string that isn't a valid number, such as int('abc'), raises a ValueError, so user input should generally be validated or wrapped in a try/except block before converting.

Conclusion: Know the Type Before You Trust the Operation

Python's dynamic typing removes the ceremony of declaring types upfront, but it doesn't remove the type rules themselves — + still means something different for strings than for numbers, and no operation silently guesses which one you meant. Know your five core types, know which ones are mutable, convert explicitly with int()/float()/str() rather than assuming, and reach for isinstance() the moment a type check is doing real work in your logic.

Practice the three exercises above, then move to the next article in this cluster, which covers Python's core data structures — lists, tuples, and dictionaries — built directly on the types covered here.

🐍 Continue the Python Cluster

Next Up: Python Lists, Tuples, and Dictionaries

The mutable vs immutable distinction from this article becomes the whole story in the next one.

▶  Read the Lists, Tuples & Dictionaries Guide