Python:__main__.py 文件详解

在 Python 项目开发中,__main__.py 是一个特殊的模块文件,它决定了当包或模块以入口程序运行时,Python 会执行什么代码。

理解 __main__.py 的作用,有助于我们构建可执行的 Python 包、组织项目结构,以及为代码提供统一的运行入口。

一、__main__.py 的作用

在两种情况下,Python 会执行 __main__.py 中的代码。

(1)以包运行

python -m package_name

比如,当你运行 python -m my_package 时,Python 会在 my_package 目录下查找并执行 __main__.py 文件。

(2)以 ZIP 压缩包运行

python my_archive.zip

如果一个 ZIP 文件的根目录中包含 __main__.py,Python 会将该 ZIP 当作可执行程序运行,并执行 __main__.py。

核心作用:

• 作为程序入口,集中定义项目启动逻辑。

• 避免在包外部直接引用内部文件启动程序。

• 让包既能被导入(作为库),又能直接运行(作为程序)。

二、基本示例

项目结构:

my_package/├── __init__.py├── __main__.py└── core.py

__main__.py 内容示例:

# my_package/__main__.pyfrom .core import run_app if __name__ == "__main__":    run_app()

core.py 内容示例:

def run_app():    print("应用已启动!")

运行方式:

python -m my_package

输出:

应用已启动!

三、与 if __name__ == "__main__" 的区别

很多人会混淆 __main__.py 与 if __name__ == "__main__":

简单来说:

• 单文件脚本:用 if __name__ == "__main__"。

• 可运行的包:用 __main__.py。

四、__main__.py 的常见用途

(1)提供命令行接口(CLI)

很多 Python 工具包(如 pip、pytest)在 __main__.py 中实现 CLI 逻辑,让用户可以直接运行:

python -m pip install requests

示例:

# __main__.pyimport sysfrom .cli import main if __name__ == "__main__":    sys.exit(main())

(2)作为应用的启动文件

在大型项目中,将所有启动逻辑集中放在 __main__.py:

# __main__.pyfrom .server import start_server if __name__ == "__main__":    print("启动 Web 服务...")    start_server()

(3)ZIP 应用打包

Python 允许将项目打包成 ZIP 并直接运行:

zip -r app.zip my_packagepython app.zip

my_package/__main__.py 会作为入口执行。

从 Python 3.5 开始,可以使用 zipapp 模块来创建可执行的 zip 文件:

python -m zipapp my_package -o app.zippython app.zip

或者:

# 也可以这样运行python -m zipapp my_package -o app.pyzpython app.pyz

这种技术常用于分发 Python 命令行工具和应用程序。

五、最佳实践

(1)保持简洁

__main__.py 中只放入口逻辑,避免直接写大量业务代码。建议将核心逻辑放在独立模块中,便于复用。

(2)明确命令行参数解析

如果包作为 CLI 工具,建议使用 argparse 或 Click 等库进行参数解析:

import argparse parser = argparse.ArgumentParser(description="示例 CLI 工具")parser.add_argument("--name", required=True, help="用户名")args = parser.parse_args() print(f"你好,{args.name}!")

(3)兼容被导入的情况

尽管 __main__.py 主要用于直接运行,但它依然可以被 import,因此要避免执行不必要的逻辑。

图片

“点赞有美意,赞赏是鼓励”

Read more

JVM 可达性分析算法

JVM 可达性分析算法

说实话,开源社区里面有很多人都在讲: 可达性算法中 JVM 会进行两次标记,第一次会标记所有对象,并找到继承实现了 finalize() 方法的对象,并查看该对象是否存在“自救”,这些内容都与《深入理解 Java 虚拟机》(后文简称为 ‘书’)中 3.2.4 生存还是死亡?这一小节存在出入,或者说几乎所有的博客都是通过阅读这一小节然后得到令人一知半解的回答,整个逻辑有点混乱,前后不搭,所有我打算总结一下 说明:虽然主要讲堆内存,但方法区也有 GC,只是条件更为苛刻(所有实例被回收、ClassLoader 被回收等)。 首先会先说明可达性分析算法的规则 其次会了解一下 finalize 方法,包括它的作用时机和作用次数 最后再来说一下 JVM 垃圾收集器根据 可达性分析算法 和 Java 对象机制怎么“两次标记”,怎么回收 Java

By Ne0inhk
图的寻路算法详解:基于深度优先搜索(DFS)的实现

图的寻路算法详解:基于深度优先搜索(DFS)的实现

图的寻路算法详解:基于深度优先搜索DFS的实现 * 一、寻路算法概述 * DFS寻路示例 * 二、算法核心思想 * 数据结构设计 * 三、算法实现详解 * 1. 核心数据结构 * 2. 构造函数初始化 * 3. DFS实现 * 4. 路径查询方法 * 四、完整代码实现 * 五、算法测试与应用 * 测试代码 * 输出结果 * 六、算法分析与优化 * 时间复杂度分析 * 空间复杂度 * 优化方向 * 七、DFS寻路与BFS寻路对比 * 八、实际应用场景 * 九、总结 🌺The Begin🌺点点关注,收藏不迷路🌺 一、寻路算法概述 图的寻路算法是图论中的基础算法之一,用于找到从一个顶点到另一个顶点的路径。深度优先搜索(DFS)是实现寻路算法的一种有效方法,它沿着图的深度方向尽可能远的搜索路径。 DFS寻路示例 0123456 从顶点0到顶点6的DFS路径可能是:

By Ne0inhk
Flutter 三方库 libsignal 的鸿蒙化适配指南 - 实现 Signal 协议加密通信、双大鼠(Double Ratchet)算法与前向安全性保障

Flutter 三方库 libsignal 的鸿蒙化适配指南 - 实现 Signal 协议加密通信、双大鼠(Double Ratchet)算法与前向安全性保障

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 libsignal 的鸿蒙化适配指南 - 实现 Signal 协议加密通信、双大鼠(Double Ratchet)算法与前向安全性保障 前言 在 Flutter for OpenHarmony 的高度安全通信领域,Signal 协议是目前全球公认的即时通讯加密标准。libsignal 是 Signal 协议的核心 Dart 实现。它能够为鸿蒙应用提供从身份认证到会话加密的全套解决方案,确保每一个字节的通信都具备前向安全性(Forward Secrecy)。本文将深入解析如何在鸿蒙端利用该库构建极致安全的加密通信能力。 一、原理解析 / 概念介绍 1.1 基础原理 Signal 协议的核心在于“双大鼠(Double Ratchet)”算法。它结合了 Diffie-Hellman

By Ne0inhk

优选算法——位运算

👇作者其它专栏 《数据结构与算法》《算法》《C++起始之路》 1.前要知识 《位操作符的妙用》 2.相关题解 2.1判定字符是否唯一 算法思路: 利用【位图】的思想,每一个【比特位】代表一个【字符】,一个int类型的变量的32位足够表示所有的小写字母。比特位里若为0,表示这个字符没有出现过;若为1,表示该字符出现过。 可以用一个【整数】来充当【哈希表】。 class Solution { public: bool isUnique(string astr) { //利用鸽巢原理优化 if(astr.size()>26) return false; int bitmap=0; for(auto i:

By Ne0inhk