惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
罗磊的独立博客
V
Visual Studio Blog
爱范儿
爱范儿
H
Help Net Security
J
Java Code Geeks
I
InfoQ
Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recorded Future
Recorded Future
Jina AI
Jina AI
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
GbyAI
GbyAI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
Scott Helme
Scott Helme
S
SegmentFault 最新的问题
S
Securelist
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
博客园_首页
B
Blog
F
Fortinet All Blogs
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
S
Secure Thoughts
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Forbes - Security
Forbes - Security
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Schneier on Security
Project Zero
Project Zero
Martin Fowler
Martin Fowler
C
Cybersecurity and Infrastructure Security Agency CISA
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic

DigitalOcean Community Tutorials

Mastering grep with Regular Expressions for Efficient Text Search It's Time to Break Up with Your Cloud: Why AI Teams are Switching We Built a Private-Document AI App to Test Platform Security. Here Is What We Could Actually Verify. PostgreSQL Explained: A Complete Beginner-to-Advanced Guide How To Install and Configure Postfix on Ubuntu How To Build a Web Application Using Flask in Python 3 Build AI Reading List with DigitalOcean Functions and Mistral How To Concatenate Strings in Python How to Allow MySQL Remote Access Securely How To Install and Use Docker on Rocky Linux How To Build a Multi-Agent AI System with Docker Agent DSPy Use Cases: Build Optimized LLM Pipelines How To Submit AJAX Forms with jQuery Build an AI-Powered GPU Fleet Optimizer with the DigitalOcean AI Platform ADK Monitor GPU Utilization in Real Time: A Complete Guide Reduce File Size of Images in Linux - CLI and GUI methods Reduce PDF File Size in Linux: Tools and Methods How To Set Up a Private Docker Registry on Ubuntu How To Troubleshoot Terraform: Errors and Fixes How to Use Go Modules Python Multiprocessing Example: Process, Pool & Queue Convert Class Components to Functional Components with React Hooks How To Install and Configure Ansible on Ubuntu LLM Tokenizers Simplified: BPE, SentencePiece, and More How To Monitor System Authentication Logs on Ubuntu How to Use Traceroute and MTR to Diagnose Network Issues How to Deploy Postgres to Kubernetes Cluster Importing Packages in Go: A Complete Guide Create RAID Arrays with mdadm on Ubuntu How To Make an HTTP Server in Go How To Set Up Time Synchronization on Ubuntu How To Use Struct Tags in Go apt-key Deprecation: Add Repositories with GPG on Ubuntu Linux ps Command: 20 Real-World Examples Python struct.pack and struct.unpack for Binary Data Deadlock in Java: Examples, Detection, and Prevention How To Use Find and Locate to Search for Files on Linux Structured Resume Skill Extraction Using Mistral-7B Inference How to Set Up NemoClaw on a DigitalOcean Droplet with 1-Click Build an End-to-End RAG Pipeline for LLM Applications From Single to Multi-Agent Systems: Key Infrastructure Needs Back Up Data to Object Storage Using Restic How to Generate Videos with LTX-2.3 on DigitalOcean GPU Droplets How To Install LAMP Stack (Apache, MySQL, PHP) on Ubuntu How to Download Files with cURL How To Use Variadic Functions in Go Generate UUIDs with uuidgen on Linux How To Use EJS to Template Your Node Application How to Install Node.js on Ubuntu (Step-by-Step Guide) MongoDB Indexes: Improve Query Performance with Node.js LLM Tool Calling with DigitalOcean AI Platform and Databases What are Text Diffusion Models? - An Overview Crafting a Game from Scratch with GPT-5.4 Building Long-Term Memory in AI Agents with LangGraph and Mem0 How To Install PHP 7.4 and Set Up a Local Development Environment on Ubuntu 20.04 Build a GraphQL API in Go to Upload Files to Spaces How To Lint and Format Code with ESLint in Visual Studio Code Train YOLO26 for Retail Object Detection on DigitalOcean GPUs How To Work with JSON in MySQL How to Use the JavaScript .map() Method Building a Scalable App with MongoDB Using DigitalOcean's MCP Server How to Create an SSH Key in Linux: Easy Step-by-Step Guide Measure MySQL Query Performance with mysqlslap How To Use *args and **kwargs in Python 3 Nemotron 3 helped me find the perfect dish rack? A2A vs MCP - How These AI Agent Protocols Actually Differ How To Install and Manage Supervisor Docker Container Images with Watchtower on Ubuntu Getting Started with Qwen3.5 Vision-Language Models How To Create a New Sudo-Enabled User on Ubuntu How to Use Ansible to Install and Set Up Docker on Ubuntu How To Enable Remote Desktop Protocol Using xrdp on Ubuntu 22.04 How To Convert a String to a List in Python How To Check If a String Contains Another String in Python How to Read a Properties File in Python Python Command Line Arguments: sys.argv, argparse, getopt Mastering Grep command in Linux/Unix: A Beginner's Tutorial Understanding Python Data Types How to Implement a Stack in C With Code Examples Python os.system() vs subprocess: Run System Commands How To Install and Use Docker Compose on Ubuntu How to Add and Delete Users on Ubuntu How To Order Query Results in Laravel Eloquent How To Define and Use Handlers in Ansible Playbooks How To Install and Use SQLite on Ubuntu How To Install and Use Homebrew on macOS How To Manage DateTime with Carbon in Laravel and PHP How To Install Git on Ubuntu How To Install and Secure Redis on Ubuntu How To Build and Install Go Programs on Linux Using ldflags to Set Version Information for Go Applications How To Build a Node.js Application with Docker How To Add JavaScript to HTML How To Reset Your MySQL or MariaDB Root Password How To Add Images in Markdown How To Set Up a Production Elasticsearch Cluster with Ansible How To Set Up a Firewall Using firewalld on CentOS Understanding Systemd Units and Unit Files How To Set Up Replication in MySQL How To Use the .htaccess File
How to Use the Python Main Function
2026-03-20 · via DigitalOcean Community Tutorials

The Python main function is the conventional entry point for a script: you define a function (typically named main) that holds your program logic and call it only when the file is run directly, not when it is imported as a module. Python does not call main() automatically; the pattern if __name__ == "__main__": is what lets you separate “run as script” from “import as module.” When the file is executed directly, the interpreter sets the special __name__ variable to "__main__", so the block under that condition runs and can call main(). When the file is imported, __name__ is set to the module name, so that block is skipped and your module can be reused without side effects. This article shows how to define and use the Python main function, how CPython assigns __name__, how to make packages runnable with __main__.py, how to integrate argparse, and how to structure scripts for testability and correct exit codes.

Key Takeaways

  • The Python main function is not special to the interpreter; you define it yourself and call it from a if __name__ == "__main__": block so it runs only when the file is executed directly.
  • CPython sets __name__ to "__main__" when you run a file with python file.py, and to the module name (filename without .py) when the file is imported, which is how the guard works.
  • Use a def main() function to hold your script logic and call it from the if __name__ == "__main__": block; use sys.exit(main()) so the process returns a proper exit code to the shell.
  • For packages, add a __main__.py in the package directory so python -m packagename runs that file as the Python entry point.
  • The if __name__ == "__main__": guard keeps top-level code from running on import, which makes scripts testable and avoids side effects when the file is used as a module.

What Is the Python Main Function?

In Python there is no built-in “main” that the interpreter runs. The Python main function is a convention: you define a function (usually named main) that contains your script’s logic and invoke it only when the file is run as the main program. This gives you a clear Python entry point and keeps the file usable as a module.

Without a guard, every top-level statement in a file runs both when you execute the file and when you import it. That leads to unwanted side effects when the file is used as a module. The standard approach is to put the call to your main function inside if __name__ == "__main__":, so the Python script execution flow runs your entry point only when the file is executed directly, not when it is imported.

The following example shows the pattern. Top-level print runs in both cases; the call to main() runs only when the file is executed directly.

print("Module loading: top-level code runs on import and on direct run")

def main():
    print("python main function: entry point when run directly")

if __name__ == "__main__":
    main()

When you run this file directly:

Module loading: top-level code runs on import and on direct run
python main function: entry point when run directly

When you import it from another script, you will see only the first line; the block under if __name__ == "__main__": does not run, so the difference between Python module vs script execution is clear.

Understanding the name Variable in Python

The __name__ global variable Python sets for every module is the key to the main-guard pattern. It is a string that identifies how the current file is being used: as the main program or as an imported module.

How CPython Assigns name

When CPython runs a file, it sets __name__ in a few common ways:

  1. Direct execution: You run python myfile.py. CPython sets __name__ to the string "__main__" for that file. So the file is treated as the Python main module.
  2. Import: Another module imports it (for example, import myfile or import pkg.myfile). CPython loads the module and sets __name__ to its import name: "myfile" in the first case and "pkg.myfile" in the second.
  3. Module as a script via -m: You run python -m some_module (or python -m pkg.myfile). Python finds that module and executes it as a script, setting __name__ to "__main__" inside that module.

So the same file can behave as either the main program or a library depending on Python import vs direct execution. The following example demonstrates both paths with annotated output.

File: greet.py

print("greet.py is executing. __name__ =", repr(__name__))

def main():
    print("Hello from main()")

if __name__ == "__main__":
    main()
    print("(Direct run: __name__ was __main__, so this block ran)")
else:
    print("(Imported: __name__ was", repr(__name__) + ", so main() was not called)")

Run directly: python greet.py

greet.py is executing. __name__ = '__main__'
Hello from main()
(Direct run: __name__ was __main__, so this block ran)

Import from another script: python -c "import greet"

greet.py is executing. __name__ = 'greet'
(Imported: __name__ was 'greet', so main() was not called)

So: when run directly, __name__ is "__main__" and main() runs; when imported, __name__ is the module name and the main block is skipped. That is the internal mechanism behind the Python main function pattern. Python interpreter execution order is always top to bottom; the only difference is the value of __name__ when your code runs.

Using if name == “main” in Python

The condition if __name__ == "__main__": is the standard way to mark the block that should run only when the file is the main program. It implements the Python reusable script pattern: the same file can be both a script and an importable module.

Anything inside that block is Python top-level code that runs only on direct execution. Typically you call a main() function there so all script logic lives in one place. If you omit the guard, every top-level statement runs on import too, which can cause side effects (prints, network calls, file writes) when the file is used as a module.

The next section ties this to testability: the guard is what lets test runners import your script without running its entry point.

Defining a def main() Function in Python

You can name your entry-point function anything, but the convention is main. Defining a def main() Python function and calling it from the if __name__ == "__main__": block keeps script logic in one place and makes the entry point obvious.

Define main() before the guard so it exists when the block runs. If the guard appears above the function definition, you will get NameError: name 'main' is not defined when the file is run directly.

Example:

import sys

def main():
    print("Running main logic")
    return 0

if __name__ == "__main__":
    sys.exit(main())

Running the file directly produces:

Running main logic

Using a single main() function is the standard Python best practices script structure for small scripts and CLI tools.

Making a Python Package Executable With main.py

A Python package (a directory containing an __init__.py) can be run as a script by adding a __main__.py file inside that directory. When you run python -m packagename, the interpreter looks for packagename/__main__.py and executes it as the Python entry point. This is how many CLI tools packaged as directories are invoked (e.g. python -m pip, python -m http.server).

Minimal layout:

mytool/
    __init__.py
    __main__.py

mytool/__init__.py (can be empty):

# Package marker; can be empty

mytool/__main__.py:

import sys

def main():
    print("Running mytool as a package")
    return 0

sys.exit(main())

Note: __main__.py is executed directly by the interpreter when you run python -m mytool, so __name__ is always "__main__" in that file. You do not need an if __name__ == "__main__": guard here unless you also intend to import __main__.py as a module, which is uncommon.

From the directory that contains mytool, run:

python -m mytool
Running mytool as a package

Python invokes mytool/__main__.py when you use python -m mytool.

Note: The parent directory containing mytool must be on sys.path (e.g. run from that directory or install the package). For more on package layout, see How to Make a Python Package.

Integrating argparse With Your Python Main Function

You can wire argparse into your Python main function by defining the parser and parsing in the if __name__ == "__main__": block, then passing the parsed namespace into main(). That keeps argument parsing at the entry point and leaves main() testable with plain values.

Example: argument definition, parsing, and passing parsed args through main().

import argparse
import sys

def main(args):
    greeting = f"Hello, {args.name}!"
    if args.loud:
        greeting = greeting.upper()
    print(greeting)
    return 0

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Echo a greeting")
    parser.add_argument("--name", default="World", help="Name to greet")
    parser.add_argument("--loud", action="store_true", help="Uppercase the greeting")
    parsed = parser.parse_args()
    sys.exit(main(parsed))

Help output: python script.py --help

usage: script.py [-h] [--name NAME] [--loud]

Echo a greeting

options:
  -h, --help    show this help message and exit
  --name NAME   Name to greet (default: World)
  --loud        Uppercase the greeting

Sample run: python script.py --name "DigitalOcean" --loud

HELLO, DIGITALOCEAN!

For more patterns, see How to Use argparse to Write Command-Line Programs in Python. For defining the functions that use those arguments, see How to Define Functions in Python 3.

Using the name Guard for Testability

The if __name__ == "__main__": guard prevents import-time side effects. When a test suite (e.g. pytest or unittest) imports your script to test its functions, only the module-level code outside the guard runs; the main block does not. So you avoid running the whole program just because you imported it.

Without the guard: script runs its logic on import, which is bad for tests.

# script_without_guard.py
def main():
    print("Doing work")

# BAD: runs on import
main()

When a test file does import script_without_guard, it will see “Doing work” printed and any side effects of main() will run. That makes tests noisy and can change global state.

With the guard: script imports cleanly; entry point runs only when executed.

# script_with_guard.py
def main():
    print("Doing work")

if __name__ == "__main__":
    main()

When a test file does import script_with_guard, only the function definition is loaded; nothing is printed and no side effects run. Tests can call script_with_guard.main() when they need to. So the guard is what makes the script both runnable and safely importable for testing.

Why Use sys.exit() in a Python Main Function

Processes report success or failure to the shell via exit codes: 0 usually means success, non-zero means an error. In Python, the process exit code is set by sys.exit(code). If you do not call it, the interpreter exits with 0 when main() returns or when the script finishes, even when your logic detected an error. Using sys.exit(main()) ties the process exit code to the return value of your Python main function.

Have main() return 0 on success and a non-zero integer on failure, then pass that to sys.exit():

import sys

def main():
    # Simulate a failure check
    if len(sys.argv) > 1 and sys.argv[1] == "--fail":
        return 1
    print("Success")
    return 0

if __name__ == "__main__":
    sys.exit(main())

When run without --fail, the script prints “Success” and exits with code 0. When run with --fail, it returns 1 and prints nothing. The shell sees that code (e.g. echo $? prints 0 or 1 after the script runs).

python script.py
Success
echo $?
0
python script.py --fail
echo $?
1

Warning: If main() does not return an integer, sys.exit(main()) may not behave as intended. sys.exit() expects an integer or an object with a compatible meaning; for clarity, have main() explicitly return 0 or a non-zero int.

So for any script that can fail, the sys.exit(main()) pattern is the right approach.

Python Main Function Best Practices

  1. Use the guard for the entry point. Always put the call to your main logic inside if __name__ == "__main__": so the file can be imported without running that logic. This is the standard Python reusable script pattern.

  2. Name the entry-point function main(). You can use another name, but def main() Python convention makes the entry point obvious to other developers and to tools.

  3. Return an exit code from main() and use sys.exit(main()). Have main() return 0 on success and a non-zero integer on failure, and call sys.exit(main()) in the guard block so the process reports the correct exit code to the shell.

  4. Keep argument parsing at the boundary. Parse argparse (or other CLI args) in the if __name__ == "__main__": block or at the start of main(), and pass parsed values into the rest of your code. That keeps main() testable with plain arguments.

  5. Avoid side effects at top level. Put only imports, constants, and function/class definitions at module level. Do not run heavy logic or I/O at top level; do it inside main() or behind the guard so imports stay fast and side-effect free.

  6. For runnable packages, use __main__.py. If your project is a package, add __main__.py and implement the entry point there so users can run it with python -m packagename.

Following these rules keeps your Python script execution flow clear, makes scripts testable and reusable as modules, and aligns with common Python best practices for script structure.

Frequently Asked Questions

What does if name == “main” mean in Python?

It means: run the following block only when this file is executed as the main program, not when it is imported as a module. When you run the file with python file.py, Python sets __name__ to "__main__", so the condition is true and the block runs. When the file is imported, __name__ is the module name, so the condition is false and the block is skipped.

What does the main() function do in Python?

The main() function is the conventional place for your script’s logic. Python does not call it automatically; you define it and call it from the if __name__ == "__main__": block. It gives you a single, clear entry point and keeps the file importable without running that logic.

Is if name == “main” necessary in Python?

It is not required by the language, but it is the standard way to separate “run as script” from “import as module.” Without it, every top-level statement runs on import too, which causes side effects and makes the file hard to test and reuse. For any file that is both run directly and imported, the guard is the recommended pattern.

What is the equivalent of the main() function in Python?

Python has no built-in main. The equivalent is to define your own function (usually main) and call it from if __name__ == "__main__":. That block is the Python entry point when the file is run directly.

What is the name variable in Python?

__name__ is a special string set by the interpreter for every module. When a file is run directly with python file.py, __name__ is "__main__". When the file is imported, __name__ is the module name (the filename without .py). The __name__ global variable Python uses is what makes the main-guard pattern work.

What is main.py used for in Python?

__main__.py is used to make a package runnable with python -m packagename. It lives inside the package directory. When you run python -m packagename, the interpreter executes packagename/__main__.py as the entry point. Many CLI tools use this so the package can be invoked as a script.

How do I pass command-line arguments to a Python main function?

Parse arguments with argparse (or another parser) at the entry point, then pass the parsed result into main(). For example: in the if __name__ == "__main__": block (or at the start of main()), call parser.parse_args() to get a namespace, then pass that namespace or its attributes into main(args) or use them inside main(). That keeps parsing at the boundary and leaves main() testable with plain values.

Why should I use sys.exit() in a Python main function?

So the process reports the correct exit code to the shell (0 for success, non-zero for failure). Have main() return that code and call sys.exit(main()) in the guard block. If you do not call sys.exit(), the process may always exit with 0 even when your logic failed, which breaks scripts and automation that rely on exit codes.

Conclusion

The Python main function pattern—using if __name__ == "__main__": and placing the main logic in a main() function—is a best practice for writing clean, reusable, and testable Python scripts. This approach allows your code to behave correctly whether it is run as a script or imported as a module, avoids top-level side effects, and enables powerful features like __main__.py for packages. By following these conventions and structuring your scripts thoughtfully, you make your Python projects easier to maintain, extend, and incorporate into larger applications or workflows.

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.