Skip to main content

Values and Types

Topic — In Python, data is not stored in rigid, statically typed boxes. Instead, every value is an object in memory that carries its own type, and variables are merely named tags pointing to those objects. This guide explores the four foundational primitive types (int, float, str, bool), type inspection via type() and isinstance(), the boolean integer inheritance surprise, floating-point precision traps, and casting rules.


1. The Core Concept​

In programming, we distinguish between two fundamental concepts:

  • A Value is the concrete piece of information (e.g., 100, 15.75, "Python", True).
  • A Type is the blueprint defining what operations are legal on that value (e.g., you can divide an int, slice a str, but cannot add an int to a str).

Python is dynamically typed: you never declare a variable's type. Python inspects the value at runtime and assigns the appropriate class blueprint automatically:

ExpressionPython InterpretationAssigned Data TypeFull Type Object
100Whole number without decimalint<class 'int'>
15.75Real number with decimal pointfloat<class 'float'>
"Python"Characters enclosed in quotesstr<class 'str'>
TrueLogical boolean keywordbool<class 'bool'>
tip

If you only take one thing from this page

In Python, variables do not have types; values have types. A variable is simply a name tag attached to an object in memory. If you reassign x = 100 and then x = "Python", the variable x has simply moved its pointer from an integer object to a string object.


2. Interactive Type Inspector Sandbox​

Click on any Python literal or expression below to inspect its evaluated type, truthiness, mutability, and runtime memory behavior:

Python Value and Type Inspector

Select a Python literal to inspect how the runtime evaluates its object metadata:

Python Assignment Expression
num_value = 100
<class 'int'>
Evaluated Value
100
type(x).__name__
int
Boolean Truthiness
True (Non-zero)
Mutability
Immutable
Runtime Insight: Arbitrary-precision integer. In Python 3, integers have no size limit—they grow as large as your system memory allows (e.g. 2**100 computes seamlessly).

3. Three Ways to Query Types in Python​


  • Syntax: isinstance(value, target_type)
  • Returns: True or False.
  • Why it's preferred: Correctly accounts for class inheritance. Also accepts a tuple of types:
    # Checks if x is either an integer or floating-point number
    if isinstance(x, (int, float)):
    print("x is numeric")

4. The Boolean Inheritance Surprise​

In Python, bool is a direct subclass of int. This historical architecture design catches many developers off guard:

issubclass(bool, int) # True
isinstance(True, int) # True! True IS an integer!

Consequences of Boolean Inheritance​

True == 1 # True
False == 0 # True
True + True # 2 (Arithmetic works!)
True * 50 # 50
warning

The If-Elif Subclass Pitfall

Because True is an instance of int, checking isinstance(val, int) before isinstance(val, bool) will falsely intercept booleans:

# BUG: True matches the int check!
if isinstance(val, int):
print("Number")
elif isinstance(val, bool): # Never reached!
print("Flag")

# FIX: Always check bool first
if isinstance(val, bool):
print("Flag")
elif isinstance(val, int):
print("Number")

5. Type Conversion and Casting Pitfalls​

Python provides built-in constructors (int(), float(), str(), bool()) to cast between types:


  • int(15.75) evaluates to 15.
  • Rule: int() truncates toward zero; it does not round to the nearest whole integer.
  • To round properly according to standard arithmetic rules, use round(15.75)   ⟹  16\implies 16.

6. Implementation Lab​

tip

Lab Exercise: Values, Types & Casting Mechanics

An interactive, fully functional Google Colab / Jupyter Notebook is available to inspect types, verify the boolean integer inheritance chain, test floating-point epsilon comparisons, and practice type casting live in your browser.

Open In Colab

How to run the lab:

  1. Click the "Open In Colab" badge above to launch the interactive notebook.
  2. Run cells sequentially to experiment with type inspection and truthiness rules.

Key Experiments to Run:

  • Experiment 1 (Type vs. Isinstance): Compare type(True) == int (False) with isinstance(True, int) (True) to see inheritance in action.
  • Experiment 2 (Floating-Point Epsilon): Evaluate 0.1 + 0.2 == 0.3 (False) and write a safe tolerance check using abs(a - b) < 1e-9.
  • Experiment 3 (Type Casting Traps): Catch ValueError on int("15.75") and demonstrate the nested casting fix int(float("15.75")).

7. Common Mistakes​


  • The Misconception: "In Python, booleans can be typed as true or false like in JavaScript."
  • Wrong Thinking: Typing flag = true.
  • The Right Principle: Python keywords are case-sensitive. true raises a NameError: name 'true' is not defined. Always capitalize: True and False.

8. Summary​

Primitive Types

  • int: Arbitrary-precision whole numbers. Division (/) always produces a float.
  • float: IEEE 754 64-bit numbers. Exact for binary fractions (0.5,0.750.5, 0.75), approximate for decimals (0.1+0.20.1 + 0.2).
  • str: Immutable text sequences. Indexed from 00 or −1-1.
  • bool: Subclass of int. True == 1, False == 0.

Runtime Inspection

  • type(x): Returns raw class object (<class 'int'>).
  • isinstance(x, T): Preferred check; respects inheritance and accepts tuples (int, float).
  • Dynamic Typing: Variables are labels; objects carry types.
  • int() vs. round(): int() truncates; round() rounds.

info

Key Takeaways

  • Values carry types: Variables are pointers to objects in memory; dynamic re-assignment changes which object the variable points to.
  • Prefer isinstance(): Use isinstance(x, (int, float)) for robust numerical validation.
  • Falsy check: Only 0,0.0,"",[],,None,0, 0.0, "", [], {}, None, and FalseFalse are falsy; all other values evaluate to True.

Next Section: Variables and Naming - exploring namespace scopes, reference assignment, and PEP 8 naming conventions.


9. Active Recall​

Test your understanding by answering first, then clicking to reveal the underlying principles.

Interactive Checkpoint Quiz​

Interactive Checkpoint: The Dynamic Typing Trap

Consider this Python snippet: x = "20"; print(x * 3). What is printed, and why?

Review Flashcards​

1. [THEORY] Why does Python evaluate 0.1 + 0.2 == 0.3 as False?

  • Base-2 Binary Fractions: Computers represent floating-point numbers in binary.
  • Just as 13=0.3333…\frac{1}{3} = 0.3333\dots has an infinite repeating decimal in base-10, 0.10.1 and 0.20.2 are infinite repeating fractions in base-2: 0.110=0.0001100110011…20.1_{10} = 0.0001100110011\dots_2
  • When truncated to 53 bits of precision, 0.1+0.20.1 + 0.2 yields: 0.3000000000000000444…0.3000000000000000444\dots
  • Safe Comparison: Never use == on floats. Use math.isclose(a, b) or abs(a - b) < 1e-9.
2. [THEORY] Why does isinstance(True, int) evaluate to True, but type(True) == int evaluates to False?

  • Inheritance: In Python, bool is a subclass of int (issubclass(bool, int) == True).
  • isinstance(obj, Class) checks if obj is an instance of Class or any class derived from it. Because True is a bool and bool inherits from int, isinstance returns True.
  • type(obj) == Class checks for exact class identity, ignoring inheritance. Because type(True) is <class 'bool'> and not <class 'int'>, it evaluates to False.
3. [PRACTICE] Why does int("15.75") raise a ValueError, and how do you fix it?

  • Base-10 Parsing Limit: The int(s) constructor expects a string consisting purely of integer digits. The character . is not a valid base-10 digit, so Python raises ValueError: invalid literal for int() with base 10: '15.75'.
  • The Fix: Parse the decimal string through float() first, then truncate to integer:
    int(float("15.75")) # Evaluates to 15
4. [ANALYZE] What is printed by print(bool("False")) and print(bool(""))?

  • print(bool("False")) prints True.
  • print(bool("")) prints False.
  • The Principle: In Python, string truthiness is determined strictly by sequence length (len(s) > 0). It does not parse the semantic English meaning of the letters inside the string. Only an empty string "" has length 0 and evaluates to False.
5. [THEORY] What does it mean that Python is dynamically typed?

  • Types Belong to Objects, Not Variables: In statically typed languages (like C or Java), a variable is declared with a fixed type (int x = 10;) and can never hold any other type.
  • In Python, variables are simply pointers (labels) in the namespace. An object on the heap carries its type header.
  • Reassigning x = 10 to x = "hello" merely rebinds the label x to a different object in memory; Python handles this without compiler errors.