Execute Program

Python for Programmers: Strict Dynamic Types

Welcome to the Strict Dynamic Types lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • Python supports static type annotations, but it's primarily a dynamically typed language.

  • In a statically typed language, we can answer the question "is this variable an integer?" without running the program. For some Python code, we may be able to visually inspect it and confidently say "this variable will be an integer at runtime." But in complex real-world code, it might be difficult to predict a variable's precise type (it might be an integer, or a float, or a null.) In fact, unless we're using Python's type annotations, Python itself doesn't know the type of anything until it actually runs the code.

  • That's the trade-off in a dynamic language: we don't have to write any type annotations, but we also can't be certain about the types.

  • Dynamic languages prioritize flexibility, which means that we can often mix types loosely. For example, many dynamic languages let us add strings to numbers, even though that usually indicates a mistake in the code.

  • Let's briefly compare Python's string behavior to four other dynamic languages: JavaScript, PHP, Perl, and Lua. As a first example, JavaScript will happily let us "add" the number 1 to the string "5".

  • >
    // This is JavaScript, not Python!
    1 + "5"
    Result:
  • You might have expected that expression to return the number 6, rather than the string '15'. That's exactly what happens in PHP.

  • >
    // This is PHP, not Python!
    1 + "5"
    Result:
  • Perl and Lua both behave like PHP: 1 + "5" returns 6. In Perl, Lua, PHP, and JavaScript, the + operator automatically converts values. But the languages don't agree on how to convert them, with JavaScript being the odd one out.

  • As we'll see throughout this course, Python is more careful with types. In Python, the + operator can't mix numbers and non-numbers. It also can't mix strings and non-strings. Trying to mix types in those ways is an error.

  • (You can type error when a code example will cause an error.)

  • >
    1 + "5"
    Result:
    TypeError: unsupported operand type(s) for +: 'int' and 'str'Pass Icon
  • >
    "5" + 1
    Result:
    TypeError: can only concatenate str (not "int") to strPass Icon
  • The important takeaway is that while Python is dynamically typed, it's more strict than JavaScript, PHP, Lua, and Perl. This strictness sets it apart from most other dynamic languages.

  • What if we really do want to combine strings and numbers? In those cases, we can perform the necessary conversions explicitly. For example, we can use the built-in str() function to convert non-string values into strings.

  • >
    str(7)
    Result:
  • >
    str(42)
    Result:
    '42'Pass Icon
  • >
    price = 120
    message = "The price is " + str(price)
    message
    Result:
    'The price is 120'Pass Icon
  • When we have an integer inside of a string, we can use int to convert it back into an integer.

  • >
    apple_count = "3"
    apple_price = 20
    int(apple_count) * apple_price
    Result:
    60Pass Icon
  • These required conversions are an important part of Python's design. They're related to an aphorism that's familiar to Python programmers: "In the face of ambiguity, refuse the temptation to guess."

  • Python tries not to guess at what we mean. Instead, it forces us to be explicit about our intent: "yes, this is a number, but we're intentionally combining it with a string."

  • We'll see many examples of Python's strictness in later lessons. We'll also see more conversion functions, like the str and int functions shown above: bool, list, dict, and others.