What is __name__ in Python?

Discover __name__ in Python: its role, the if __name__ == '__main__' condition, practical use cases, and best practices for structuring your programs.
9 min read
Believemy logo

Definition of __name__ in Python

In Python, __name__ is a built-in special variable (also called a dunder attribute, short for "double underscore") that is automatically defined by the Python interpreter in every module. Its value depends on the execution context of the file:

  • If the file is executed directly (as the main script), __name__ equals the string "__main__".
  • If the file is imported as a module from another file, __name__ equals the module's name (i.e., the filename without the .py extension).

This variable is at the heart of one of the most important conventions in Python: the famous if __name__ == "__main__" block. If you follow our complete Python course, you will discover that this concept is essential for writing professional and reusable code.

Good to know

__name__ is one of Python's special attributes (like __doc__, __file__, __package__). They are called dunder attributes because they are surrounded by double underscores (double underscores → dunder).

 

How does __name__ work?

To fully understand __name__, you need to visualize what happens when Python executes a file. The interpreter automatically assigns metadata to each loaded module, and __name__ is one of them.

Direct execution of a script

When you launch a Python file directly from the command line (for example python my_script.py), the interpreter sets __name__ to "__main__" for that file:

PYTHON
# file: my_script.py
print(__name__)

Result when running python my_script.py:

PYTHON
__main__

 

Import as a module

Now, if you import that same file from another script, the value of __name__ changes:

PYTHON
# file: other_script.py
import my_script

Result when running python other_script.py:

PYTHON
my_script

As you can see, __name__ now equals "my_script" (the filename without .py) and no longer "__main__". This distinction is what makes __name__ so powerful.

 

The if __name__ == "__main__" block

The if __name__ == "__main__" construct is probably the most common pattern in Python. You will find it in virtually every professional project. Its role is simple: execute a block of code only when the file is run directly, and not when it is imported.

Fundamental example

PYTHON
# file: calculator.py

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

if __name__ == "__main__":
    # This block only runs if the file is executed directly
    print("Calculator test")
    print(f"3 + 5 = {add(3, 5)}")
    print(f"10 - 4 = {subtract(10, 4)}")
    print(f"6 * 7 = {multiply(6, 7)}")

When you run python calculator.py, you get:

PYTHON
Calculator test
3 + 5 = 8
10 - 4 = 6
6 * 7 = 42

But if you import this module from another file:

PYTHON
# file: application.py
import calculator

result = calculator.add(100, 200)
print(result)  # 300

Only 300 is displayed. The calculator's test block does not execute, because __name__ equals "calculator" and not "__main__".

 

Why is this so important?

Without this guard, every import would trigger the execution of all the "loose" code in the module. Imagine a module that launches a web server or performs heavy computations: you would not want that to happen on every import. The if __name__ == "__main__" block gives you full control over what runs and when.

 

Advanced practical examples

Structuring a project with __name__

In a well-structured project, each module can be both a function library and an executable script. Here is a more complete example:

PYTHON
# file: utils.py

def format_name(first_name, last_name):
    """Formats a full name with proper capitalization."""
    return f"{first_name.capitalize()} {last_name.upper()}"

def validate_email(email):
    """Basic check that an email contains an @."""
    return "@" in email and "." in email

def generate_identifier(first_name, last_name):
    """Generates a unique identifier based on the name."""
    return f"{first_name.lower()}.{last_name.lower()}"


if __name__ == "__main__":
    # Quick manual tests
    print("=== Utils module tests ===")
    
    formatted_name = format_name("john", "doe")
    print(f"Formatted name: {formatted_name}")
    
    valid_email = validate_email("john@example.com")
    print(f"Valid email: {valid_email}")
    
    identifier = generate_identifier("John", "Doe")
    print(f"Identifier: {identifier}")

You can thus quickly test your module with python utils.py, while importing it cleanly elsewhere with import utils.

 

Using a main() function

A very widespread convention is to def a function named main() and call it in the guard block. This makes the code cleaner and more testable:

PYTHON
# file: app.py
import sys

def process_data(file):
    """Processes data from a file."""
    print(f"Processing {file}...")
    # Processing logic here
    return True

def display_help():
    """Displays program help."""
    print("Usage: python app.py ")
    print("Options:")
    print("  -h, --help    Display this help")

def main():
    """Main entry point of the program."""
    if len(sys.argv) < 2:
        display_help()
        sys.exit(1)
    
    file = sys.argv[1]
    
    if file in ("-h", "--help"):
        display_help()
    else:
        success = process_data(file)
        if success:
            print("Processing completed successfully!")

if __name__ == "__main__":
    main()

This approach is recommended because it allows you to reuse the main() logic in unit tests without having to execute the entire script.

 

__name__ in classes and functions

It is important to note that __name__ also exists as an attribute of class and functions:

PYTHON
class Vehicle:
    pass

def accelerate():
    pass

print(Vehicle.__name__)  # Vehicle
print(accelerate.__name__)  # accelerate

# Useful for debugging and logging
def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function: {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log_call
def calculate_total(price, quantity):
    return price * quantity

calculate_total(10, 5)
# Prints: Calling function: calculate_total

Here, __name__ returns the name of the class or function as a string, which is extremely useful for docstring, debugging, and metaprogramming.

 

__name__ and packages

In the context of packages (directories containing an __init__.py file), __name__ reflects the full module path:

PYTHON
# Structure:
# my_project/
#   __init__.py
#   core/
#     __init__.py
#     engine.py

# In my_project/core/engine.py:
print(__name__)  
# When imported: "my_project.core.engine"
# When executed directly: "__main__"

 

Summary table

Execution contextValue of __name__Example
Script executed directly"__main__"python script.py
Imported moduleModule nameimport script → "script"
Module in a packageFull pathimport pkg.mod → "pkg.mod"
Class attributeClass nameMyClass.__name__ → "MyClass"
Function attributeFunction namemy_func.__name__ → "my_func"

 

Best practices

Here are the rules to follow to get the most out of __name__ in your Python projects:

1. Always use the guard block

Every Python file that may be both imported AND executed should contain an if __name__ == "__main__" block. This is a universal convention and a sign of professional code.

PYTHON
# ✅ Good practice
def my_function():
    return "Result"

if __name__ == "__main__":
    print(my_function())

# ❌ Bad practice
def my_function():
    return "Result"

print(my_function())  # Also runs on import!

 

2. Delegate to a main() function

Rather than placing all the logic inside the if block, create a dedicated main() function. This makes testing easier and improves readability.

PYTHON
# ✅ Recommended
def main():
    # All logic here
    pass

if __name__ == "__main__":
    main()

 

3. Use __name__ for logging

Using __name__ in print and logging module configuration is a standard practice:

PYTHON
import logging

# Creates a logger with the current module's name
logger = logging.getLogger(__name__)

def my_function():
    logger.info("Function executed")
    # The log will automatically display the module name

This approach is powerful because it allows you to trace exactly which module emitted a log message, which is essential in large-scale projects.

 

4. Do not modify __name__

Warning

Although it is technically possible to modify the value of __name__, you should never do so. This variable is managed by the Python interpreter and modifying it can lead to unpredictable behavior.

 

5. Separate definitions from execution

Place all your function, class, and constant definitions at the top of the file. The if __name__ == "__main__" block should be the last element of the file:

PYTHON
# 1. Imports
import os
import sys

# 2. Constants
VERSION = "1.0.0"

# 3. Classes and functions
class Application:
    pass

def start():
    pass

# 4. Entry point (always last)
if __name__ == "__main__":
    start()

 

Common mistakes to avoid

Here are the most frequent pitfalls related to __name__:

Forgetting quotes around __main__

PYTHON
# ❌ Error: __main__ without quotes does not exist as a variable
if __name__ == __main__:  # NameError!
    pass

# ✅ Correct: it is a string
if __name__ == "__main__":
    pass

 

Confusing module __name__ and class __name__

PYTHON
class MyEngine:
    pass

# __name__ at module level = execution context
print(__name__)  # "__main__" or module name

# __name__ on the class = class name
print(MyEngine.__name__)  # "MyEngine"

 

Running code at global level without a guard

PYTHON
# ❌ Dangerous: this code runs on every import
connection = create_database_connection()
result = long_query(connection)

# ✅ Protected by the guard
if __name__ == "__main__":
    connection = create_database_connection()
    result = long_query(connection)

 

Frequently asked questions

Question

What does if __name__ == "__main__" exactly mean in Python?

This condition checks whether the Python file is being executed directly (and not imported as a module). When you run a file with python file.py, the interpreter assigns the value "__main__" to that file's __name__ variable. The condition is therefore true and the code block executes. However, if this file is imported by another script via import file, __name__ equals "file" and the block is skipped. This is an essential mechanism for separating reusable code from execution code.

 

Question

Can you have multiple if __name__ == "__main__" blocks in the same file?

Technically, yes, Python will not prevent you from doing so. However, it is strongly discouraged. The convention is to have a single if __name__ == "__main__" block placed at the very end of the file. Having multiple blocks makes the code confusing and hard to maintain. If you need to perform multiple actions, group them in a single main() function.

 

Question

Is __name__ mandatory in all Python files?

No, __name__ is not mandatory. The variable always exists automatically, but you are not required to use the if __name__ == "__main__" block. However, it is recommended to add it whenever your file contains code that should not run during an import. For files that are only libraries of def (functions) or class, it is good practice to include this block for placing quick tests.

 

Question

How can I learn to properly use __name__ and structure my Python projects?

To master __name__ and all of Python's professional conventions, we recommend following our dedicated Python course on Believemy. You will learn not only the language syntax but also best practices for project structuring, module and package management, and patterns used in the industry. Regular practice with real-world projects is the best way to naturally integrate these concepts into your code.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.