console_scripts必须写为entry_points={"console_scripts": ["name=package.module:func"]}或[project.entry-points."console_scripts"]下name = "package.module:func",确保模块可导入、func是函数对象且包结构正确。

entry_points里console_scripts怎么写才生效
不写对格式,安装后 pip install -e . 也没法在终端直接敲命令。核心是:键必须是 console_scripts,值必须是 name=package.module:func 这种字符串列表,不能是字典、不能缩进、不能拼错冒号。
-
name是你希望用户在终端输入的命令名,比如mytool -
package.module必须是可 import 的路径(注意不是文件路径),且该模块得在sys.path里 —— 通常意味着它得在项目根目录或src/下,并在setup.py或pyproject.toml中正确声明包结构 -
func必须是函数对象,不能是字符串,也不能带括号;它最好接受sys.argv[1:]或用argparse解析参数 - 如果用
pyproject.toml,要写在[project.entry-points."console_scripts"]下,注意双引号不能省
setup.py 和 pyproject.toml 两种写法差异在哪
旧写法用 setup.py,新写法用 pyproject.toml,但底层都走 setuptools 的 entry point 机制。区别主要在配置位置和语法容错性:
-
setup.py:在setup()调用里传entry_points={"console_scripts": ["mycmd=myapp.cli:main"]}—— 注意外层是字典,内层是字符串列表 -
pyproject.toml:必须用 TOML 表语法,写成[project.entry-points."console_scripts"],然后换行写mycmd = "myapp.cli:main";等号前后空格可选,但值必须是双引号包裹的字符串 - 如果同时存在
setup.py和pyproject.toml,现代 pip(≥21.3)优先读pyproject.toml,setup.py会被忽略 —— 别以为改了 setup.py 就生效
为什么装完命令找不到,或者报 ImportError
最常见原因不是 entry_points 写错,而是模块导入链断了。执行 mycmd 时,Python 实际是在新进程里做 import myapp.cli,所以任何 import 失败都会表现为 ModuleNotFoundError 或 ImportError。
- 检查
myapp/__init__.py是否缺失(尤其在src/结构下,src/myapp/需配packages=find_packages(where="src")和package_dir={"": "src"}) - 运行
python -c "import myapp.cli; print(myapp.cli.main)"看能否成功 import 并拿到函数对象 - 确认
myapp/cli.py没有顶层代码触发异常(比如误写了requests.get(...)却没装 requests) - 虚拟环境里装包后,别忘了关掉旧 shell 再新开一个——zsh/bash 的命令哈希缓存可能记着“没这个命令”
如何调试 console_scripts 生成的 wrapper 脚本
pip 安装时会在 venv/bin/(Linux/macOS)或 venv/Scripts/(Windows)下生成一个纯 Python 的 wrapper 脚本,名字就是你定义的 name。它不复杂,但能帮你定位问题。
立即学习“Python免费学习笔记(深入)”;
- 用
which mycmd找到脚本路径,直接cat或less查看内容,你会看到类似from myapp.cli import main; main()的调用 - 把里面那行
main()改成print("argv:", sys.argv); main(),再运行,就能确认参数是否透传进来 - 如果 wrapper 脚本根本没生成,说明
pip install没识别到 entry_points —— 检查pyproject.toml的表头拼写,或setup.py是否被正确加载(比如用了 PEP 517 构建但没配build-backend)
真正卡住的地方往往不在 entry_points 语法本身,而在包结构和 import 可见性。写完先确保 python -m myapp.cli 能跑通,再指望终端命令可用。


















