Python 命令行参数解析教程
1. 基础入门:sys.argv 快速获取
如果你只想拿到用户敲进去的原始字符串,sys.argv 是最快的方式。它是一个列表,第一个元素永远是脚本自身的名称(如 script.py),后面依次跟着所有空格分隔的输入。
import sys
print("接收到的完整命令行参数列表:", sys.argv)
将上面的代码保存为 basic_argv.py,在终端里运行:
python basic_argv.py hello world 123
输出将是:
接收到的完整命令行参数列表: ['basic_argv.py', 'hello', 'world', '123']
这种方法虽然直接,但缺点也很明显:没有类型检查、没有约束逻辑、没有帮助文档——工具稍微复杂一点,你自己和你的用户都会崩溃。
2. 核心工具:argparse 标准库
只要你的命令行工具需要正式一点的用户体验,Python 自带的 argparse 就是首选。它不需要额外安装,能自动生成 -h/--help 帮助文档,并且覆盖了绝大多数命令行场景。
2.1 三步搭建框架
使用 argparse 的流程非常简单,只要三步:
- 创建一个
ArgumentParser 对象(相当于一个“参数收纳箱”)
- 通过
add_argument() 往箱子里添加各种参数规则
- 调用
parse_args() 解析参数,得到一个属性化对象
import argparse
# 第一步:搭建收纳箱
parser = argparse.ArgumentParser(
prog="my_cli_tool", # 工具的正式名称(帮助文档中显示)
description="这是一个示例工具的简介",
epilog="© 2024 我的开发笔记" # 帮助文档结尾的附注
)
# 第二步:添加参数
parser.add_argument("file_path", help="要操作的文件路径")
# 第三步:解析并使用
if __name__ == "__main__":
args = parser.parse_args()
print(f"开始处理文件:{args.file_path}")
就这么简单!运行 python my_cli_tool.py -h,你会立刻看到一份结构清晰的帮助信息。
2.2 五种常用的参数类型
① 位置参数(必填,没有短/长选项)
位置参数按用户输入的顺序绑定,适合逻辑上必须先填的核心内容,例如文件路径、操作名。
parser.add_argument(
"outfile",
help="数据库备份的输出文件路径" # 一定要写 help!
)
② 可选参数(带有短/长选项)
可选参数可以以任意顺序给出,适合开关、配置项等非核心内容。短选项一般是单字母(如 -u),长选项更易读(如 --user)。
parser.add_argument(
"-u", "--user", # 可以单独写 -u 或 --user,也可以同时写
required=True, # 可选参数也能变成必填
help="登录数据库的用户名"
)
③ 带默认值的可选参数
给可选参数设置默认值能减轻用户的负担,默认值会在帮助文档的 (default: xxx) 里自动展示。
parser.add_argument(
"--host",
default="localhost",
help="MySQL 主机地址"
)
④ 类型转换与验证
默认情况下,所有参数都被当作字符串。通过 type 可以自动转换成 int、float 等类型,甚至自定义验证函数。
# 直接转换整数
parser.add_argument(
"--port",
type=int,
default=3306,
help="MySQL 端口号"
)
# 自定义验证:限制端口范围
def check_port(port_str):
port = int(port_str)
if 1 <= port <= 65535:
return port
raise argparse.ArgumentTypeError(f"端口必须在 1-65535 之间,你输入的是 {port}")
parser.add_argument(
"--safe-port",
type=check_port,
default=3306,
help="安全的 MySQL 端口号"
)
提示:自定义验证函数会在用户输入非法值时马上抛出清晰的错误,比解析后再检查体验好得多。
⑤ 布尔开关参数
这种参数不需要后面跟值,只要出现在命令行里,就自动设为 True(或者 False)。通过 action 参数控制。
# 只要写 -g 就设为 True
parser.add_argument(
"-g", "--gz",
action="store_true",
help="是否启用 GZIP 压缩备份文件"
)
# 写 --no-color 就设为 False(默认是 True)
parser.add_argument(
"--no-color",
action="store_false",
dest="enable_color", # 修改解析后对象的属性名
default=True,
help="是否禁用彩色输出"
)
⑥ 限定选择的参数
使用 choices 限定输入只能是指定列表中的某个值,帮助文档也会自动列出这些选项。
parser.add_argument(
"--format",
choices=["json", "xml", "csv"],
default="json",
help="备份文件的输出格式"
)
2.3 完整的实战示例:数据库备份工具
把上面的知识点整合起来,写一个虽然简单但五脏俱全的 MySQL 备份工具模板。
import argparse
def backup_database(outfile, host, port, user, password, database, gz):
"""模拟数据库备份的核心逻辑"""
print(f"✅ 开始准备备份任务")
print(f"📁 输出文件:{outfile}{'.gz' if gz else ''}")
print(f"🔗 连接信息:{user}@{host}:{port}/{database}")
if gz:
print("📦 GZIP 压缩已启用")
if __name__ == "__main__":
# 1. 搭收纳箱
parser = argparse.ArgumentParser(
prog="db_backup",
description="轻量级 MySQL 数据库本地备份工具",
epilog="⚠️ 使用前请确保已安装 mysqldump"
)
# 2. 添加所有参数
parser.add_argument("outfile", help="备份文件的本地路径(不带.gz后缀)")
parser.add_argument("--host", default="localhost", help="MySQL 主机地址")
def check_port(port_str):
port = int(port_str)
if 1 <= port <= 65535:
return port
raise argparse.ArgumentTypeError(f"端口必须在 1-65535 之间")
parser.add_argument("--port", type=check_port, default=3306, help="MySQL 端口号")
parser.add_argument("-u", "--user", required=True, help="登录用户名")
parser.add_argument("-p", "--password", required=True, help="登录密码")
parser.add_argument("--database", required=True, help="要备份的数据库名")
parser.add_argument("-g", "--gz", action="store_true", help="启用 GZIP 压缩")
# 3. 解析并运行
args = parser.parse_args()
backup_database(
args.outfile,
args.host,
args.port,
args.user,
args.password,
args.database,
args.gz
)
现在运行 python db_backup.py -h 看一眼自动生成的帮助文档,你会感到真正的省心——再也不用自己手写一堆说明文字了。
2.4 进阶:分组 + 子命令
当参数数量超过 10 个,或者一个工具内有多个独立功能(比如“备份”和“恢复”),就可以用分组和子命令来让用户的输入更有条理。
参数分组
将相关参数归到同一个标题下,帮助文档立马变得清晰:
# 分组1:连接配置
conn_group = parser.add_argument_group("连接配置", "关于 MySQL 服务器的设置")
conn_group.add_argument("--host", default="localhost")
conn_group.add_argument("--port", type=int, default=3306)
conn_group.add_argument("-u", "--user", required=True)
conn_group.add_argument("-p", "--password", required=True)
# 分组2:备份配置
backup_group = parser.add_argument_group("备份配置", "关于备份文件的设置")
backup_group.add_argument("outfile")
backup_group.add_argument("--format", choices=["sql", "csv"], default="sql")
backup_group.add_argument("-g", "--gz", action="store_true")
子命令
子命令相当于把一个大型工具拆成若干个独立的小命令,就像 git add 与 git commit 那样。使用 subparsers 可以轻松实现。
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog="db_tool", description="MySQL 管理工具集")
# 必须设置 dest,这样才能知道用户选择了哪个子命令
subparsers = parser.add_subparsers(dest="command", required=True, help="可用的子命令")
# 子命令1:backup
backup_parser = subparsers.add_parser("backup", help="备份数据库到本地")
backup_parser.add_argument("outfile", help="输出文件路径")
# 这里可以继续添加 --host、--user 等参数...
# 子命令2:restore
restore_parser = subparsers.add_parser("restore", help="从本地文件恢复数据库")
restore_parser.add_argument("infile", help="输入的备份文件路径")
# ...
args = parser.parse_args()
if args.command == "backup":
print("执行备份逻辑")
elif args.command == "restore":
print("执行恢复逻辑")
3. 现代替代方案(需要安装)
虽然 argparse 已经足够强大,但如果你追求更简洁的语法或者更现代的交互体验,可以了解一下下面这两个第三方库。
3.1 Click
Click 使用装饰器来定义命令,语法非常优雅。它还贴心地提供了密码隐藏等功能。
import click
@click.command()
@click.argument("outfile")
@click.option("--host", default="localhost", help="MySQL 主机")
@click.option("--port", default=3306, type=int, help="MySQL 端口")
@click.option("-u", "--user", required=True, help="用户名")
@click.password_option("-p", "--password", help="密码") # 输入时不回显
@click.option("-g", "--gz", is_flag=True, help="启用压缩")
def db_backup(outfile, host, port, user, password, gz):
click.echo(f"备份到 {outfile}")
if __name__ == "__main__":
db_backup()
安装:pip install click
3.2 Typer(基于 Click)
Typer 完全拥抱 Python 类型提示,代码的可读性和维护性直接拉满,还支持自动补全。
import typer
app = typer.Typer()
@app.command()
def backup(
outfile: str,
host: str = "localhost",
port: int = 3306,
user: str = typer.Option(..., help="用户名"), # ... 表示必填
password: str = typer.Option(..., prompt=True, hide_input=True, help="密码"),
gz: bool = typer.Option(False, "--gz", "-g", help="启用压缩")
):
typer.echo(f"✅ 备份到 {outfile}")
if __name__ == "__main__":
app()
安装:pip install typer
4. 最佳实践总结
- 一定要写
help:这是对用户(以及未来的你自己)最基本的尊重
- 设置合理的默认值:例如端口默认
3306、格式默认 json
- 参数命名要直观:长选项尽量用完整单词,短选项选有意义的单字母
- 尽早验证输入:利用
type 自定义验证函数,比解析完再检查友好得多
- 复杂工具使用子命令:避免所有参数堆在一起
5. 快速决策表
无论你的项目最终选择哪一个,argparse 都是每个 Python 开发者必须扎实掌握的基础,在此基础上,再根据具体需求挑选更现代的替代品就好。