Dynamic Typing in Python

One of Python’s most distinctive features is its dynamic typing. This means you don’t have to explicitly declare the data type of a variable when you create it. The Python interpreter automatically determines the data type based on the value you assign. Furthermore, a variable’s type can change throughout the program’s execution.

What is Dynamic Typing?

In a dynamically typed language like Python, the same variable can hold values of different types at different times.

Let’s see a classic example of this in action.

Pyground

A variable `x` is first an integer, then a string, and finally a list. Track its type at each stage.

Expected Output:


Value: 10, Type: <class 'int'>
Value: Hello, Python!, Type: <class 'str'>
Value: [1, 2, 3], Type: <class 'list'>

Output:

As you can see, x seamlessly transitioned from an int to a str and then to a list without any complaints from Python.

Dynamic Typing vs. Static Typing

This is in sharp contrast to statically typed languages (like Java, C++, or C#), where you must declare the variable’s data type before you can use it, and that type cannot change.

In Python, this is perfectly valid:

my_variable = 100       # my_variable is an int
my_variable = "Now I'm a string" # This is allowed!

Advantages and Disadvantages of Dynamic Typing

Dynamic typing is a double-edged sword. It offers flexibility but requires caution.

Advantages:

  • Flexibility & Rapid Development: It’s faster to write code because you don’t have to specify types. This is great for scripting and rapid prototyping.
  • Readability: Code can be cleaner and less cluttered with type declarations.
  • Code Reusability: Functions and methods can operate on a variety of types, as long as they support the required operations (this is known as “duck typing”).

Disadvantages:

  • Potential for Runtime Errors: Since types are not checked until the code is executed, a TypeError might only appear when the program is running. For example, trying to add a number to a string.
  • Harder to Debug: Type-related errors can be trickier to track down because they occur at runtime.
  • Performance Overhead: The interpreter has to do extra work at runtime to keep track of and check the types of variables, which can make dynamically typed languages slightly slower than their static counterparts.
⚠️

The Danger of Unexpected Type Changes

Dynamic typing can lead to bugs that are hard to find. Imagine a function that expects a number, but later in your code, the variable you pass to it has been accidentally changed to a string. This will cause a TypeError at runtime.

Let’s see this in a practice problem.

Pyground

Consider a function that calculates the price after tax. What happens if you accidentally pass a string to it? Fix the code so it handles this gracefully.

Expected Output:


Correct usage: 105.0
Incorrect usage: Error: Both price and tax rate must be numbers.

Output:

This example shows why it’s important to be mindful of variable types in your Python code, even though the language is flexible. Using checks like isinstance() can help prevent unexpected runtime errors.