Python Variables and Types — Core Concepts

Python’s Dynamic Type System

Python is dynamically typed: variables don’t have types, values do. A variable is just a name bound to an object, and that binding can change at any time.

x = 42        # x points to an integer object
x = "hello"   # x now points to a string object
x = [1, 2, 3] # x now points to a list object

This flexibility speeds up development but can cause surprises. A variable that should be a number might unexpectedly hold None, and you won’t find out until the code runs and crashes.

The Core Built-in Types

Integers (int)

Whole numbers, positive or negative. Unlike most languages, Python integers can be arbitrarily large — there’s no overflow.

small = 42
huge = 10 ** 100   # A googol — no problem for Python
negative = -17

Python can calculate 2 ** 1000 without breaking a sweat. Most languages would overflow their 64-bit integer type.

Floats (float)

Numbers with decimal points, stored as 64-bit IEEE 754 floating-point values.

price = 9.99
pi = 3.14159

Floats have precision limits — a fact that surprises many beginners:

print(0.1 + 0.2)   # 0.30000000000000004

This isn’t a Python bug; it’s how floating-point math works in every language (and every CPU). For financial calculations, use the decimal module instead.

Strings (str)

Text. Python strings are immutable — once created, they can’t be changed. Operations that appear to modify strings actually create new ones.

greeting = "Hello"
greeting = greeting + ", world!"   # New string, not modification

Python supports f-strings (since 3.6), which are the cleanest way to embed values in text:

name = "Alice"
age = 30
print(f"{name} is {age} years old.")   # Alice is 30 years old.

Booleans (bool)

True or False. Booleans are a subclass of integers in Python (True == 1, False == 0), which has some odd implications:

print(True + True)   # 2
print(True * 5)      # 5

None (NoneType)

None is Python’s null value — it means “no value” or “nothing here.” It’s its own type with only one possible value.

result = None
if result is None:
    print("No result yet")

Use is None not == None to check for None. The difference matters with custom objects that override ==.

Type Conversion

You can explicitly convert between types:

int("42")       # → 42
float("3.14")   # → 3.14
str(100)        # → "100"
bool(0)         # → False (0, "", [], None are all falsy)
bool(1)         # → True (everything else is truthy)

Python also converts types automatically in some situations (implicit conversion), but being explicit is usually safer and clearer.

Checking Types

x = 42
print(type(x))        # <class 'int'>
print(isinstance(x, int))   # True
print(isinstance(x, (int, float)))  # True — is it an int OR float?

isinstance is usually better than type(x) == int because it respects inheritance.

Variable Naming Rules

  • Can contain letters, numbers, underscores
  • Must start with a letter or underscore (not a number)
  • Case-sensitive: score and Score are different variables
  • Python convention (PEP 8): use snake_case for variable names
player_score = 100    # Good
playerScore = 100     # Works, but not Pythonic
PLAYER_SCORE = 100    # Convention for constants

Common Misconception: Python Is “Weakly Typed”

Python is actually strongly typed. It won’t silently convert types in ways that lose information:

"5" + 5   # TypeError — no automatic conversion

JavaScript would silently give you "55". Python raises an error. “Dynamic” means type-checking happens at runtime, not compile time. “Strong” means type rules are enforced consistently.

Type Hints (Optional, But Useful)

Since Python 3.5, you can annotate variables and function signatures with type hints:

name: str = "Alice"
age: int = 30

def greet(person: str) -> str:
    return f"Hello, {person}!"

Python itself ignores these at runtime — they’re documentation for humans and tools. Type checkers like mypy and editors like VS Code use them to catch errors before you run the code.

One Thing to Remember

In Python, types belong to values, not variables — a variable is just a name pointing to an object, and that object knows its own type. This makes Python flexible but means type errors show up at runtime, not compile time.

pythonvariablesdata-typestype-system

See Also

  • Python Async Await Async/await helps one Python program juggle many waiting jobs at once, like a chef who keeps multiple pots moving without standing still.
  • Python Basics Python is the programming language that reads like plain English — here's why millions of beginners (and experts) choose it first.
  • Python Booleans Make Booleans click with one clear analogy you can reuse whenever Python feels confusing.
  • Python Break Continue Make Break Continue click with one clear analogy you can reuse whenever Python feels confusing.
  • Python Closures See how Python functions can remember private information, even after the outer function has already finished.