在我们写 Python 脚本时,经常需要接收外部参数,比如文件名、数量、配置等。最原始的方式是直接使用 sys.argv,但这种方式既不安全也不友好。今天我们就来用 Python 内置标准库 argparse来实现CLI 工具。
为什么要放弃 sys.argv [1]?
import sysfilename = sys.argv[1]count = int(sys.argv[2])
上面的写法能用,但也有一些问题:不传参数直接崩溃:IndexError;类型错误直接崩溃:ValueError;没有默认值、没有校验、没有说明
所有 argparse 脚本都从这几行开始,它会自动处理参数、校验、帮助文档。
import argparse# 创建解析器parser = argparse.ArgumentParser(description="我的命令行工具")# 解析参数args = parser.parse_args()
只要加上这几行,脚本自动拥有 --help 功能,不用写任何额外代码。
位置参数按顺序传递,必须填写,常用于文件名、路径等。
parser.add_argument("filename", help="输入文件路径")parser.add_argument("count", help="处理数量")
使用方式:python script.py data.txt 10
可选参数以 -- 开头,支持短别名 -x,还能设置默认值。
# 完整名 + 短别名 + 默认值parser.add_argument("--output", "-o", default="output.txt", help="输出文件")# 布尔开关(出现就是 True,不出现就是 False)parser.add_argument("--verbose", "-v", action="store_true", help="显示详细日志")
自动类型校验:再也不用手动转 int/float。argparse 可以自动校验类型,传错会给出清晰提示,不会直接崩溃。
# 整数类型parser.add_argument("--count", type=int, default=10)# 浮点数类型parser.add_argument("--rate", type=float, default=1.5)# 只能从指定选项中选择parser.add_argument("--format", choices=["json", "csv", "txt"], default="json")
使用方式:python script.py input.txt --output result.txt -v
有时候我们想可选参数必须传,或者接收多个值(列表)。
强制必传的可选参数
parser.add_argument("--title", required=True, help="文章标题(必填)")
接收多个值(变成列表)
# 接收一个或多个值:--tags python cli tutorialparser.add_argument("--tags", nargs="+", help="标签列表")# 接收零个或多个值(可以为空)parser.add_argument("--files", nargs="*")
使用后直接得到 Python 列表:
for tag in args.tags: print(tag)
真正的 CLI 工具(如 git、pip、docker)都支持子命令,argparse 也能轻松实现。
parser = argparse.ArgumentParser(description="发布队列管理")subparsers = parser.add_subparsers(dest="command", required=True)# 子命令:listlist_parser = subparsers.add_parser("list", help="显示队列")# 子命令:addadd_parser = subparsers.add_parser("add", help="添加文章")add_parser.add_argument("--title", required=True)
使用方式如下:
python publish.py list python publish.py add --title "我的文章"
几乎所有 CLI 工具都用 -v / --verbose 开启调试日志,这是标准写法。
import loggingparser.add_argument("--verbose", "-v", action="store_true")args = parser.parse_args()logging.basicConfig( level=logging.DEBUG if args.verbose else logging.INFO)
总结一下,如果想要CLI工具更像那么回事,不妨试试argparse