用 argparse 编写一个真正处理文件的命令行工具

读懂参数解析之后,可以再向前一步:让参数确实控制输入、输出与校验,而不是只打印“正在处理”。下面实现一个文本行数统计工具。

先约定命令行接口

python count_lines.py notes.txt --output result.json --min-length 5 --verbose

这个命令读取 notes.txt,统计去掉首尾空白后长度至少为 5
的行,将结果写入新的
result.json,并显示处理结果。字符长度按 Python 字符串的
len 计算,不是模型 token 数。

完整实现

import argparse
import json
from pathlib import Path

def nonnegative_int(value):
    try:
        number = int(value)
    except ValueError as exc:
        raise argparse.ArgumentTypeError("必须是整数") from exc
    if number < 0:
        raise argparse.ArgumentTypeError("不能小于 0")
    return number

def main():
    parser = argparse.ArgumentParser(description="统计符合长度条件的文本行")
    parser.add_argument("input", type=Path, help="UTF-8 文本文件")
    parser.add_argument("--output", type=Path, default=Path("result.json"))
    parser.add_argument("--min-length", type=nonnegative_int, default=1)
    parser.add_argument("--verbose", action="store_true")
    args = parser.parse_args()

    if not args.input.is_file():
        parser.error("输入路径必须是已存在的文件")
    if args.input.resolve() == args.output.resolve():
        parser.error("输入和输出不能是同一个文件")

    try:
        lines = args.input.read_text(encoding="utf-8").splitlines()
        count = sum(len(line.strip()) >= args.min_length for line in lines)
        result = {"total_lines": len(lines), "matched_lines": count,
                  "min_length": args.min_length}
        with args.output.open("x", encoding="utf-8") as stream:
            json.dump(result, stream, ensure_ascii=False, indent=2)
            stream.write("\n")
    except (OSError, UnicodeError) as exc:
        parser.error(str(exc))

    if args.verbose:
        print(f"匹配 {count}/{len(lines)} 行,结果:{args.output}")

if __name__ == "__main__":
    main()

输出使用 "x"
模式创建:如果文件已存在,程序报告错误,避免覆盖已有结果。输出目录需要预先存在。

这些参数分别承担什么职责

input 是位置参数,默认必须提供;--output
是带默认值的选项;--verbose
是布尔开关;--min-length
通过自定义转换函数同时进行整数解析和非负校验。

type=Path
只把字符串转换为路径对象,不检查文件是否存在。存在性、输入输出冲突等要求属于业务校验,必须自己补上。

选项形式也不意味着一定可以省略:add_argument 支持
required=True。此外,choices
可以限制枚举值,nargs 可以声明多个值。Python argparse
文档

用一个小输入验证行为

假设文件内容为:

hello
hi
world

执行 --min-length 5 后,total_lines 为
3,matched_lines 为
2。传入负数、缺失文件或已存在的输出路径,都应得到明确错误。

从这个工具迁移到 RAG
项目时,可以把读取文件的逻辑替换为解析、切分或建立索引,但仍保留清晰的参数约定与失败提示。

自测:为何不能只写 type=int
就认为阈值有效?因为它能排除非整数,却不能排除业务上不允许的负数。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇