Entry Points 是 Python 包注册可执行命令的唯一标准机制,通过 setup.py 或 pyproject.toml 中声明 console_scripts 映射(如 mytool = mytool.cli:main),安装时生成对应脚本;函数需可导入且接受 sys.argv,不依赖 name == '__main__';错误常静默发生于安装阶段。

因为它是让 Python 包安装后自动注册可执行命令的唯一标准机制,不依赖 shell 脚本或手动 PATH 操作。
Entry Points 怎么把函数变成命令行命令
本质是 setup.py 或 pyproject.toml 里声明一个映射:命令名 → 模块内具体函数。安装时 pip 把这个映射写进 egg-info 或 dist-info 元数据,然后 pip 或 setuptools 生成对应脚本(比如放在 venv/bin/xxx)。
- 必须用
console_scripts这个 entry point group,其他 group(如pytest11)不触发命令生成 - 目标函数必须接受
sys.argv或类似参数,且通常不带参数调用(main()),由工具自己解析 - 函数本身不需
if __name__ == '__main__':—— 安装后它就不是靠直接运行 .py 文件启动的
setup.py 和 pyproject.toml 的写法差异
老项目用 setup.py,新项目推荐 pyproject.toml,但语义一致,只是语法不同:
#[pyproject.toml] [project.entry-points."console_scripts"] mytool = "mytool.cli:main"
对应 mytool/cli.py 里有 def main(): ...;而 setup.py 写法是:
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
立即学习“Python免费学习笔记(深入)”;
entry_points={
"console_scripts": ["mytool = mytool.cli:main"]
}
- 冒号左边是命令名(用户敲的),右边是
module:callable,中间不能有空格 - 模块路径必须能被 Python 导入(即包已正确安装,且
__init__.py存在或 PEP 420 启用) - 如果 callable 是类,必须实现
__call__;如果是静态方法,需确保能被 importable 路径访问到
常见报错和调试方法
装完命令找不到?多数是 entry point 没生效或路径没刷新:
-
pip install -e .必须加-e(editable mode),否则修改pyproject.toml后不重生成脚本 -
which mytool返回空?检查是否在正确 venv 里,或运行pip list确认包已安装 - 报错
ModuleNotFoundError: No module named 'mytool'?说明导入路径不对,尝试在 Python 里import mytool.cli验证 - 报错
AttributeError: module 'mytool.cli' has no attribute 'main'?确认函数名拼写、大小写、是否被条件 import 掩盖
为什么不用 argparse + __main__ 直接跑?
可以,但那就不是“安装即用”的 CLI 工具了:
- 用户得记住
python -m mytool.cli,而不是简洁的mytool - 无法跨 Python 环境复用(比如系统 Python 装的工具,在 venv 里不可见)
- 没法和其他工具链集成(如 pipx、Homebrew、CI/CD 的
command -v检查) - Windows 下没
__main__.py或 shebang,直接运行更麻烦
Entry Points 是 PEP 376 和 PEP 517 定义的标准行为,不是 setuptools 特性 —— 即使换用 flit 或 hatch 构建,只要声明 console_scripts,效果一样。真正容易被忽略的是:它不校验函数是否存在,只校验字符串格式;出错往往在安装那一刻静默失败,而非运行时报错。

















