How to define a variable in Python

Learn how to define a variable in Python. This guide covers different methods, tips, real-world applications, and common error debugging.

How to define a variable in Python
Published on: 
Fri
Feb 6, 2026
Updated on: 
Tue
Feb 24, 2026
The Replit Team Logo Image
The Replit Team

Variables are a core concept in Python that let you store and manage data. You use the assignment operator, =, to turn abstract information into something your code can use.

You'll learn the techniques to declare variables, along with practical tips and real-world applications. You will also get advice to debug common issues and help you write cleaner, more effective code.

Basic variable assignment

name = "John"
age = 30
print(f"Name: {name}, Age: {age}")--OUTPUT--Name: John, Age: 30

In this example, the variable name is assigned a string value, while age is assigned an integer. Python’s dynamic typing means you don’t need to declare a variable’s type beforehand. The interpreter infers it at runtime, which allows for more flexible and concise code.

The print() function then uses an f-string for output. Prefixing the string with an f lets you embed variables like {name} and {age} directly. This is a modern, readable, and efficient way to format strings in Python.

Basic variable definition techniques

Now that you understand simple assignment, you can write more efficient and readable code by working with various data types and using smarter assignment techniques.

Using different data types

integer_var = 10
float_var = 3.14
string_var = "Hello"
boolean_var = True
print(type(integer_var), type(float_var), type(string_var), type(boolean_var))--OUTPUT--<class 'int'> <class 'float'> <class 'str'> <class 'bool'>

Python variables are versatile and can hold different kinds of data. The code assigns four fundamental types, and you can use the built-in type() function to inspect a variable and confirm what kind of data it holds.

  • integer_var holds an int, which is a whole number.
  • float_var stores a float, a number with a decimal point.
  • string_var is assigned a str, or a sequence of characters.
  • boolean_var contains a bool, representing either True or False.

Multiple variable assignment

x, y, z = 1, 2.5, "Python"
a = b = c = 100
print(f"x={x}, y={y}, z={z}")
print(f"a={a}, b={b}, c={c}")--OUTPUT--x=1, y=2.5, z=Python
a=100, b=100, c=100

Python provides shortcuts for assigning variables to make your code cleaner. You can initialize multiple variables with different values on a single line—a technique known as unpacking.

  • The line x, y, z = 1, 2.5, "Python" assigns 1 to x, 2.5 to y, and "Python" to z.
  • Alternatively, you can use chained assignment like a = b = c = 100 to set multiple variables to the same value at once.

Variable naming conventions

user_name = "alice"      # snake_case (recommended)
UserAge = 25             # PascalCase
isActive = True          # camelCase
_private_var = "secret"  # starting with underscore
print(user_name, UserAge, isActive, _private_var)--OUTPUT--alice 25 True secret

Choosing a consistent naming style makes your code much easier to read. While Python allows different formats, the community has settled on a few key conventions you'll see everywhere.

  • The snake_case style, like user_name, is the standard for variables and functions.
  • You'll encounter PascalCase (UserAge) for class names and camelCase (isActive) in some existing codebases.
  • A leading underscore, as in _private_var, is a convention that tells other developers a variable is intended for internal use.

Advanced variable concepts

Beyond simple assignment, you can write more predictable and maintainable code by managing variable scope, adding type hints, and defining constants for fixed values.

Type hinting with variables

from typing import List, Dict, Union

name: str = "Alice"
age: int = 30
scores: List[int] = [95, 87, 92]
user: Dict[str, Union[str, int]] = {"name": "Bob", "age": 25}
print(f"{name}: {age}, Scores: {scores}")--OUTPUT--Alice: 30, Scores: [95, 87, 92]

Type hints are optional annotations that improve code clarity by specifying the intended data type for a variable, like name: str. It's important to know that Python's interpreter doesn't enforce these hints at runtime. They're primarily for static analysis tools and to help other developers understand your code.

  • For simple types, the syntax is straightforward, as seen with age: int.
  • For complex data structures, you import helpers from the typing module. For instance, scores: List[int] clearly indicates a list of integers.
  • You can even define variables that hold multiple types. Union[str, int] signals that a value can be either a string or an integer, which is useful for flexible dictionaries like user.

Using global and local variables

global_var = "I'm global"

def show_variables():
   local_var = "I'm local"
   print(global_var)
   print(local_var)

show_variables()
print(global_var)--OUTPUT--I'm global
I'm local
I'm global

A variable's scope determines where it can be accessed. Variables defined outside any function, like global_var, are global and can be used anywhere in your script. This is why it can be printed both inside and outside the show_variables() function.

  • In contrast, local_var is a local variable. It's created inside the function and only exists there.
  • You can't access local_var from outside the function—it's confined to its local scope.

Using constants and immutable variables

import enum

PI = 3.14159  # Convention for constants (uppercase)

class Color(enum.Enum):
   RED = 1
   GREEN = 2
   BLUE = 3

print(f"PI: {PI}, Red value: {Color.RED.value}")--OUTPUT--PI: 3.14159, Red value: 1

Python doesn't have true constants, but you can signal that a value shouldn't change by naming it in all caps, like PI. This is a widely followed convention that relies on developer discipline.

  • For a more robust solution, you can use the enum module to create immutable groups of related values.
  • The Color class inherits from enum.Enum, making members like Color.RED unchangeable. You can retrieve their assigned values using the .value attribute.

Move faster with Replit

Replit is an AI-powered development platform that transforms natural language into working applications. You can describe what you want to build, and Replit Agent creates it—complete with databases, APIs, and deployment.

The variable definition techniques you've learned are the foundation of any program. Replit Agent can take these concepts and turn them into production-ready tools.

  • Build a user profile system that correctly assigns names, ages, and active statuses to variables with different data types like str, int, and bool.
  • Create a configuration manager that uses constants for fixed values like API keys and enums for predefined settings.
  • Deploy a data validation service that uses type hints like Dict and List to ensure incoming information matches a required structure.

Turn your concept into a working application by describing it in plain English. Try Replit Agent to see it write, test, and deploy your code automatically.

Common errors and challenges

Even with the basics down, you'll run into a few common pitfalls when defining and using variables in Python.

Forgetting to use global when modifying variables

It’s easy to get tripped up by variable scope. While you can read a global variable from within a function without any issue, trying to modify it directly will cause problems. Python will assume you’re creating a new local variable instead of changing the global one.

  • If you try to reassign a global variable inside a function, you’ll often get an UnboundLocalError because Python thinks you’re using a local variable before it has been assigned a value.
  • To fix this, you must explicitly tell Python you intend to modify the global variable by using the global keyword at the start of your function.

Using mutable objects as default arguments

This is a classic gotcha for many developers. When you use a mutable object—like a list or a dictionary—as a default argument in a function, it’s only created once. Every subsequent call to that function that relies on the default will share and modify the very same object, leading to unexpected behavior.

  • For example, if a function with a default list argument items=[] appends a new value, that value will still be there the next time you call the function.
  • The standard practice is to use None as the default and then create a new list or dictionary inside the function if the argument is None.

Modifying lists through multiple references

When you assign a list to a new variable, you aren’t creating a copy. Instead, you’re creating another reference that points to the exact same list in memory. This means any changes you make through one variable will be reflected in the other.

  • If you have list_a = [1, 2, 3] and then set list_b = list_a, appending an item to list_b will also change list_a.
  • This happens because both variables point to the same underlying data. To work independently, you need to create an explicit copy, for instance, by using the copy() method.

Forgetting to use global when modifying variables

You can read a global variable inside a function, but modifying it is another story. Python will think you're creating a new local variable, which causes an UnboundLocalError when you use an operator like += before assigning it locally.

The following code demonstrates this exact problem when trying to increment a global counter.

counter = 0

def increment_counter():
   counter += 1  # This will cause an UnboundLocalError
   return counter

print(increment_counter())

The increment_counter() function attempts to modify counter with the += operator. Because counter isn't declared as global within the function, Python assumes it's a new local variable that hasn't been assigned, causing the error. The corrected code below resolves this.

counter = 0

def increment_counter():
   global counter
   counter += 1
   return counter

print(increment_counter())

The fix is to add global counter at the start of the increment_counter() function. This line tells Python you intend to work with the existing global variable, not create a new local one.

  • With this declaration, the += operator can now correctly modify the original counter variable that lives outside the function.
  • This is a common pattern you'll need anytime a function must change the value of a global variable.

Using mutable objects as default arguments

A function's default arguments are created only once. If you use a mutable object like a list, every call that uses the default will modify the same list, leading to bugs that can be hard to track. The following code shows this problem in action.

def add_item(item, inventory=[]):
   inventory.append(item)
   return inventory

print(add_item("sword"))
print(add_item("shield"))  # Both items end up in the same inventory

The second call to add_item doesn't start with a fresh list. It appends "shield" to the same list from the first call, which is why both items appear in the final output. The corrected code demonstrates the proper way to handle this.

def add_item(item, inventory=None):
   if inventory is None:
       inventory = []
   inventory.append(item)
   return inventory

print(add_item("sword"))
print(add_item("shield"))  # Creates separate inventories

The corrected add_item function sets the default argument to None. It then creates a new list [] inside the function only if one isn't provided. This simple pattern ensures each function call gets a fresh, independent list, preventing the shared state that causes unexpected behavior.

  • You should always use this approach when a function's default argument is a mutable type like a list or dictionary.

Modifying lists through multiple references

It's a common misconception that assigning a list to a new variable creates a copy. In reality, you're just creating another pointer to the original list. Any modification made through one variable will impact the other, as the code below illustrates.

original = [1, 2, 3]
duplicate = original
duplicate.append(4)
print(f"Original: {original}, Duplicate: {duplicate}")

Since duplicate is just another name for original, appending 4 modifies both variables. This demonstrates they aren't independent lists. The corrected code below shows how to achieve the expected result.

original = [1, 2, 3]
duplicate = original.copy()
duplicate.append(4)
print(f"Original: {original}, Duplicate: {duplicate}")

The fix is to use the copy() method, which creates a new, independent list—a shallow copy. Now, when you modify duplicate, the original list remains untouched because they’re no longer pointing to the same data in memory.

  • You should use copy() whenever you need to change a list without altering the original source.

Real-world applications

With a firm grasp on defining variables and avoiding common errors, you can now build practical applications for everyday business needs.

Calculating inventory value with the * operator

The multiplication operator, *, lets you perform straightforward business calculations, like finding the total value of your inventory by multiplying stock quantity and price.

product_name = "Laptop"
stock_quantity = 15
price = 899.99
inventory_value = stock_quantity * price
print(f"Product: {product_name}")
print(f"Total inventory value: ${inventory_value:.2f}")

This code defines variables like stock_quantity and price to calculate an inventory's total value. The final output is handled by a print() statement that uses an f-string for clean, readable formatting.

  • The most important part is the expression {inventory_value:.2f}. It’s a formatting specifier that tells Python to round the number to two decimal places.
  • This technique is crucial for financial applications, ensuring you can display currency values correctly and professionally.

Processing user data with dictionary variables

You can group dictionaries into a list to manage structured records like user profiles, making it simple to loop through the data and perform calculations.

users = [
   {"name": "Alice", "age": 28, "premium": True},
   {"name": "Bob", "age": 35, "premium": False},
   {"name": "Charlie", "age": 22, "premium": True}
]

total_age = 0
premium_count = 0
for user in users:
   total_age += user["age"]
   if user["premium"]:
       premium_count += 1

avg_age = total_age / len(users)
print(f"Average user age: {avg_age:.1f}")
print(f"Number of premium users: {premium_count}")

This pattern is a fundamental way to extract insights from structured data. The code starts with a list of dictionaries, a common format for records like user profiles. It then initializes two counters, total_age and premium_count, to zero.

  • The loop iterates through each user, accessing dictionary values with keys like user["age"].
  • An if statement evaluates the boolean premium key to filter and count specific users.

Finally, it performs a simple calculation to find the average and uses len() to get the list size. This approach is highly scalable for processing larger datasets.

Get started with Replit

Turn your knowledge into a real tool. Tell Replit Agent to "build an inventory value calculator" or "create a currency converter that uses variables for exchange rates" and watch it happen.

The agent writes the code, tests for errors, and deploys your app automatically. Start building with Replit.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.

Get started for free

Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.