golang命令行参数解析工具插件库argparse的使用

Golang命令行参数解析工具插件库argparse的使用

简介

Go语言的标准库flag在命令行参数解析方面功能有限,无法与Python的argparse模块相媲美。argparse库的目标是为Go带来与Pythonargparse相同的易用性和灵活性。

安装

使用以下命令安装argparse:

$ go get -u -v github.com/akamensky/argparse

基本使用

下面是一个基本示例,展示如何使用argparse创建一个简单的打印程序:

package main

import (
	"fmt"
	"github.com/akamensky/argparse"
	"os"
)

func main() {
	// 创建新的解析器对象
	parser := argparse.NewParser("print", "Prints provided string to stdout")
	// 创建字符串参数
	s := parser.String("s", "string", &argparse.Options{Required: true, Help: "String to print"})
	// 解析输入
	err := parser.Parse(os.Args)
	if err != nil {
		// 出错时打印错误和使用说明
		// 也可以通过传递-h或--help标志来实现
		fmt.Print(parser.Usage(err))
	}
	// 打印收集到的字符串
	fmt.Println(*s)
}

基本选项

创建解析器实例并传递程序名称和描述:

parser := argparse.NewParser("progname", "Description of my awesome program. It can be as long as I wish it to be")

字符串参数

var myString *string = parser.String("s", "string", ...)

位置参数

var myString *string = parser.StringPositional(nil)
var myString *string = parser.FilePositional(nil)
var myString *string = parser.FloatPositional(nil)
var myString *string = parser.IntPositional(nil)
var myString *string = parser.SelectorPositional([]string{"a", "b"}, nil)
var myString1 *string = parser.StringPositional(Options{Default: "beep"})

选择器参数

var mySelector *string = parser.Selector("d", "debug-level", []string{"INFO", "DEBUG", "WARN"}, ...)

字符串列表

var myStringList *[]string = parser.StringList("s", "string", ...)

列表参数

var myList *[]string = parser.List("H", "hostname", ...)

标志参数

var myFlag *bool = parser.Flag("f", "force", ...)

标志计数器

var myFlagCounter *int = parser.FlagCounter("v", "verbose", ...)

整数参数

var myInteger *int = parser.Int("i", "integer", ...)

整数列表

var myIntegerList *[]int = parser.IntList("i", "integer", ...)

浮点数参数

var myFloat *float64 = parser.Float("f", "float", ...)

浮点数列表

var myFloatList *[]float64 = parser.FloatList("f", "float", ...)

文件参数

var myLogFile *os.File = parser.File("l", "log-file", os.O_RDWR, 0600, ...)

文件列表

var myLogFiles *[]os.File = parser.FileList("l", "log-file", os.O_RDWR, 0600, ...)

子命令

可以使用parser.NewCommand()command.NewCommand()实现子命令:

// 动态获取参数值和是否已解析
var myInteger *int = parser.Int("i", "integer", ...)
parser.Parse()
fmt.Printf("%d", *parser.GetArgs()[0].GetResult().(*int))
fmt.Printf("%v", *parser.GetArgs()[0].GetParsed())

基本选项结构

Option结构定义如下:

type Options struct {
	Required bool
	Validate func(args []string) error
	Help     string
	Default  interface{}
}

示例:

dirpath := parser.String("d", "dirpath",
			 &argparse.Options{
			 	Required: false,
				Help: "the input files' folder path",
				Default: "input",
			})

注意事项

  1. 短参数必须是单个字符,以单破折号"-"开头
  2. 如果不方便,可以通过传递空字符串""作为第一个参数完全跳过短参数
  3. 只有parser.Flag()parser.FlagCounter()的短参数可以组合成单个参数
  4. 长参数必须指定且不能为空,以双破折号"–"开头
  5. 不能定义两个相同的参数
  6. 预定义了-h|--help参数
  7. parser.Parse()在出现问题时返回错误,但不涵盖所有情况
  8. 任何未解析的参数都将被视为错误

位置参数

位置参数有以下特性和条件:

  • 总是在子命令和非位置参数之后解析
  • 总是设置Required=False
  • 仅当拥有该参数的命令或子命令"发生"时才使用默认值
  • 按命令根->叶左->右的顺序解析(广度优先)

贡献

欢迎贡献代码!可以参与以下任务:

  • 添加更多示例
  • 提高代码质量
  • 添加更多参数选项
  • 提高测试覆盖率
  • 为项目编写wiki

致谢

感谢Python开发者提供了优秀的argparse模块,启发了这个Go包的开发。


更多关于golang命令行参数解析工具插件库argparse的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang命令行参数解析工具插件库argparse的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang 命令行参数解析工具 argparse 使用指南

argparse 是一个受 Python 同名模块启发的 Go 语言命令行参数解析库,提供了简单易用的 API 来定义和解析命令行参数。

安装

go get github.com/akamensky/argparse

基础用法

1. 创建解析器

package main

import (
	"fmt"
	"github.com/akamensky/argparse"
	"os"
)

func main() {
	// 创建解析器
	parser := argparse.NewParser("myprogram", "这是一个示例程序")
	
	// 添加参数
	name := parser.String("n", "name", &argparse.Options{
		Required: true,
		Help:    "用户姓名",
	})
	
	age := parser.Int("a", "age", &argparse.Options{
		Help:    "用户年龄",
		Default: 18,
	})
	
	// 解析参数
	err := parser.Parse(os.Args)
	if err != nil {
		fmt.Print(parser.Usage(err))
		return
	}
	
	fmt.Printf("你好, %s! 年龄: %d\n", *name, *age)
}

2. 参数类型

argparse 支持多种参数类型:

// 字符串参数
strArg := parser.String("s", "string", &argparse.Options{
	Help: "字符串参数",
})

// 整数参数
intArg := parser.Int("i", "int", &argparse.Options{
	Help: "整数参数",
})

// 布尔参数
boolArg := parser.Flag("b", "bool", &argparse.Options{
	Help: "布尔参数",
})

// 浮点数参数
floatArg := parser.Float("f", "float", &argparse.Options{
	Help: "浮点数参数",
})

// 列表参数
listArg := parser.List("l", "list", &argparse.Options{
	Help: "列表参数",
})

3. 位置参数

file := parser.StringPositional(&argparse.Options{
	Help: "要处理的文件",
})

4. 子命令

// 创建主解析器
parser := argparse.NewParser("git", "版本控制工具")

// 添加子命令
cloneCmd := parser.NewCommand("clone", "克隆仓库")
pullCmd := parser.NewCommand("pull", "拉取更新")

// 为子命令添加参数
repo := cloneCmd.String("r", "repo", &argparse.Options{
	Required: true,
	Help:    "仓库地址",
})

// 解析
err := parser.Parse(os.Args)
if err != nil {
	fmt.Print(parser.Usage(err))
	return
}

if cloneCmd.Happened() {
	fmt.Printf("正在克隆仓库: %s\n", *repo)
} else if pullCmd.Happened() {
	fmt.Println("正在拉取更新...")
}

高级特性

1. 参数验证

port := parser.Int("p", "port", &argparse.Options{
	Help:    "端口号",
	Default: 8080,
	Validate: func(arg int) error {
		if arg < 1 || arg > 65535 {
			return fmt.Errorf("端口号必须在1-65535之间")
		}
		return nil
	},
})

2. 互斥参数

group := parser.Mutex()
inputFile := group.String("i", "input", &argparse.Options{Help: "输入文件"})
inputText := group.String("t", "text", &argparse.Options{Help: "输入文本"})

3. 环境变量支持

apiKey := parser.String("", "api-key", &argparse.Options{
	Help:    "API密钥",
	EnvVar:  "API_KEY", // 从环境变量读取
	Default: "",        // 默认值
})

完整示例

package main

import (
	"fmt"
	"github.com/akamensky/argparse"
	"os"
)

func main() {
	parser := argparse.NewParser("fileprocessor", "处理文件的工具")

	// 添加参数
	input := parser.String("i", "input", &argparse.Options{
		Required: true,
		Help:    "输入文件路径",
	})

	output := parser.String("o", "output", &argparse.Options{
		Help:    "输出文件路径",
		Default: "output.txt",
	})

	verbose := parser.Flag("v", "verbose", &argparse.Options{
		Help:    "显示详细输出",
	})

	workers := parser.Int("w", "workers", &argparse.Options{
		Help:    "工作线程数",
		Default: 4,
		Validate: func(arg int) error {
			if arg < 1 || arg > 16 {
				return fmt.Errorf("工作线程数必须在1-16之间")
			}
			return nil
		},
	})

	// 解析参数
	err := parser.Parse(os.Args)
	if err != nil {
		fmt.Print(parser.Usage(err))
		return
	}

	// 使用参数
	if *verbose {
		fmt.Printf("开始处理文件: %s\n", *input)
		fmt.Printf("工作线程数: %d\n", *workers)
	}

	// 模拟文件处理
	fmt.Printf("处理完成,结果保存到: %s\n", *output)
}

对比其他库

argparse 相比标准库 flag 包有以下优势:

  1. 更接近 Python 的 argparse 风格,对熟悉 Python 的开发者更友好
  2. 支持更丰富的参数类型和验证
  3. 自动生成帮助信息
  4. 支持子命令

相比 cobra 等更复杂的 CLI 库,argparse 更加轻量级,适合中小型项目。

总结

argparse 是一个简单易用的 Go 命令行参数解析库,特别适合需要快速构建命令行工具的场景。它提供了清晰的 API 和自动生成的帮助信息,能够满足大多数命令行参数处理需求。

回到顶部