๐Ÿ“ Python

if __name__ == "__main__": the Python entry point

P
Author
PyLand Team
๐Ÿ“…
Published
14.08.2026
โฑ๏ธ
Reading time
4 min
๐Ÿ‘๏ธ
Views
43
๐ŸŒฑ
Level
Beginner

The if __name__ == "__main__" guard defines a Python program’s entry point: it distinguishes direct file execution from importing the file as a module and prevents the main workflow from running accidentally.

if __name__ == "__main__":
    main()

It separates the program definitionโ€”constants, classes, and functionsโ€”from running the program.

The syntax may look unusual, but it is not a special command and main is not a required function name. It compares two ordinary strings, while main() is simply the function the author chose for the main scenario.

How Python executes a file

Python reads a module from top to bottom. Imports, assignments, and function calls run immediately:

print("Module is loading")


def greet():
    print("Hello")


greet()

Both print() and greet() run during direct execution and during import. def greet(): only creates the function, but the greet() line calls it.

The guard limits the call to direct execution:

def greet():
    print("Hello")


if __name__ == "__main__":
    greet()

What name contains

Python automatically creates __name__ for every module.

When you run a file directly:

python main.py

its value is:

__name__ == "__main__"

When another file imports it:

import main

__name__ contains the module name, "main". The condition is false, so the program does not start by itself.

You can see the difference yourself:

print(__name__)
python main.py
# __main__

python -c "import main"
# main

Why use a main() function

def load_data():
    return [1, 2, 3]


def main():
    data = load_data()
    print(data)


if __name__ == "__main__":
    main()

python main.py calls main(). With import main, the functions become available to another module or test, but print() does not run.

This is especially important when a program:

  • sends an API request;
  • reads input();
  • starts an endless menu;
  • creates or deletes a file;
  • changes data in an external service.

Importing such a module must not perform those actions automatically.

What is a side effect

A side effect changes program state or the outside world. For example:

response = requests.get(API_URL)
answer = input("Choose an option: ")
Path("result.json").write_text("{}")

At module level, these lines run immediately during import. A test may unexpectedly call the network, another module may wait for input, or importing a utility may create a file.

Move calls into functions and start them from main():

def main():
    response = requests.get(API_URL, timeout=10)
    print(response.status_code)


if __name__ == "__main__":
    main()

Importing requests, defining API_URL, and defining main() are safe; the network request starts only when the function is called.

Temporary code during development

Before the final main() exists, protect temporary checks too:

if __name__ == "__main__":
    try:
        print(load_data())
    except ValueError as error:
        print(f"Error: {error}")

Later, replace temporary code with the final entry point:

def main():
    # main program scenario
    ...


if __name__ == "__main__":
    main()

This keeps an intermediate file safe to import in tests during development.

What stays outside the block

Imports, constants, and function definitions normally stay outside:

import os

API_URL = "https://example.com/api"


def fetch_data():
    ...

They prepare the module. Calls that start the scenario belong inside main() or the guarded block.

Loading settings can also stay outside when it only reads local values:

load_dotenv()
API_KEY = os.getenv("API_KEY")

Validate the key and make network requests inside functions called by main(). Then --help, tests, and imported helpers can work without contacting the API.

An entry point in a multi-file project

Consider this structure:

weather_app/
โ”œโ”€โ”€ main.py
โ”œโ”€โ”€ api.py
โ””โ”€โ”€ formatting.py

api.py provides functions:

def get_weather(city):
    ...

main.py assembles the scenario:

from api import get_weather


def main():
    city = input("City: ").strip()
    weather = get_weather(city)
    print(weather)


if __name__ == "__main__":
    main()

Now api.py can be reused by another interface, such as a Telegram bot or web application, without starting console input.

Entry points and argparse

Argument parsing is also part of running a program:

import argparse


def build_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument("name")
    return parser


def main():
    args = build_parser().parse_args()
    print(f"Hello, {args.name}!")


if __name__ == "__main__":
    main()

Tests can import build_parser() separately. parse_args() runs only during direct execution and does not try to parse the test runner’s arguments during import.

Why this helps tests

# main.py
def calculate_total(prices):
    return sum(prices)


def main():
    print(calculate_total([10, 20, 30]))


if __name__ == "__main__":
    main()

A test can safely import the function:

from main import calculate_total


def test_calculate_total():
    assert calculate_total([10, 20, 30]) == 60

Importing prints no result, requests no input, and contacts no external service.

Common mistakes

Using the wrong variable name:

if name == "main":
    main()

Use two underscores on each side:

if __name__ == "__main__":
    main()

Do not forget to call the function:

# Wrong
if __name__ == "__main__":
    main

The call needs parentheses: main().

Another mistake is calling main() before the guard:

# Wrong: runs during import
main()

if __name__ == "__main__":
    main()

Keep only the guarded call.

Do not define every function inside the block either:

# Poor structure: greet does not exist after import main
if __name__ == "__main__":
    def greet():
        return "Hello"

Define functions outside and only call them inside the block.

Is the guard always necessary

A two-line disposable script does not require it. Use the guard when code:

  • contains several functions;
  • will be imported or tested;
  • uses APIs, files, or user input;
  • provides a CLI or menu;
  • may become part of a larger project.

It is a small habit that makes a module safer to reuse.

Quick check

Create main.py:

def greet():
    return "Hello"


def main():
    print(greet())


if __name__ == "__main__":
    main()

Test both cases:

python main.py
python -c "import main; print(main.greet())"

The first command starts the program. In the second, importing prints nothing by itself; output appears only because greet() is called explicitly.

The final rule is simple:

direct run โ†’ __name__ is "__main__" โ†’ main() runs
import     โ†’ __name__ is the module name โ†’ main() does not run

Your reaction to the article

๐Ÿ’ฌ Comments (0)

๐Ÿ” Sign in to leave a comment
๐Ÿšช Login
๐Ÿ’ญ

No comments yet

Be the first to share your opinion about this article!

๐Ÿ”— Similar

Similar articles

Continue learning with these materials

๐Ÿ“

strip() and lower(): Preparing User Text ๐Ÿงน

A user may enter the correct word with extra spaces or different letter case. Python...

๐Ÿ“… 11.08.2026 ๐Ÿ‘๏ธ 49
๐Ÿ“

ord(), chr(), and Cyclic Letter Shifts in Python ๐Ÿ”

A string contains characters, but a computer stores every character as a numeric code. Python...

๐Ÿ“… 09.08.2026 ๐Ÿ‘๏ธ 87
๐Ÿ“

How Functions Work Together in Python ๐Ÿงฉ

A small function normally handles one clear task. A real program, however, contains several tasks:...

๐Ÿ“… 09.08.2026 ๐Ÿ‘๏ธ 76
๐ŸŽ“ Continue learning

Courses that cover this material

Visit the course to apply this material in practice.

API in Practice: Interact with Any Service Open course curriculum