Golang : pflag 包简介
笔者在前文中介绍了 Golang 标准库中 flag 包的用法,事实上有一个第三方的命令行参数解析包 pflag 比 flag 包使用的更为广泛。pflag 包的设计目的就是替代标准库中的 flag 包,因此它具有更强大的功能并且与标准的兼容性更好。本文将介绍 pflag 包与 flag 包相比的主要优势,如果你还不了解 flag 包的的用法,请参考《Golang : flag 包简介》一文。本文的演示环境为 ubuntu 18.04。
pflag 包的主要特点
pflag 包与 flag 包的工作原理甚至是代码实现都是类似的,下面是 pflag 相对 flag 的一些优势:
- 支持更加精细的参数类型:例如,flag 只支持 uint 和 uint64,而 pflag 额外支持 uint8、uint16、int32 等类型。
- 支持更多参数类型:ip、ip mask、ip net、count、以及所有类型的 slice 类型。
- 兼容标准 flag 库的 Flag 和 FlagSet:pflag 更像是对 flag 的扩展。
- 原生支持更丰富的功能:支持 shorthand、deprecated、hidden 等高级功能。
安装 pflag 包
本文介绍 doker 源代码中引用的 pflag 包 github.com/spf13/pfla,用下面的命令安装该包:
$ go get github.com/spf13/pflag
入门 demo
在 Go workspace 的 src 目录下创建 pflagdemo 目录,并在目录下创建 main.go 文件,编辑其内容如下:
package main import flag "github.com/spf13/pflag"
import (
"fmt"
"strings"
) // 定义命令行参数对应的变量
var cliName = flag.StringP("name", "n", "nick", "Input Your Name")
var cliAge = flag.IntP("age", "a",, "Input Your Age")
var cliGender = flag.StringP("gender", "g","male", "Input Your Gender")
var cliOK = flag.BoolP("ok", "o", false, "Input Are You OK")
var cliDes = flag.StringP("des-detail", "d", "", "Input Description")
var cliOldFlag = flag.StringP("badflag", "b", "just for test", "Input badflag") func wordSepNormalizeFunc(f *flag.FlagSet, name string) flag.NormalizedName {
from := []string{"-", "_"}
to := "."
for _, sep := range from {
name = strings.Replace(name, sep, to, -)
}
return flag.NormalizedName(name)
} func main() {
// 设置标准化参数名称的函数
flag.CommandLine.SetNormalizeFunc(wordSepNormalizeFunc) // 为 age 参数设置 NoOptDefVal
flag.Lookup("age").NoOptDefVal = "" // 把 badflag 参数标记为即将废弃的,请用户使用 des-detail 参数
flag.CommandLine.MarkDeprecated("badflag", "please use --des-detail instead")
// 把 badflag 参数的 shorthand 标记为即将废弃的,请用户使用 des-detail 的 shorthand 参数
flag.CommandLine.MarkShorthandDeprecated("badflag", "please use -d instead") // 在帮助文档中隐藏参数 gender
flag.CommandLine.MarkHidden("badflag") // 把用户传递的命令行参数解析为对应变量的值
flag.Parse() fmt.Println("name=", *cliName)
fmt.Println("age=", *cliAge)
fmt.Println("gender=", *cliGender)
fmt.Println("ok=", *cliOK)
fmt.Println("des=", *cliDes)
}
代码本身很简单,也添加了注释,这里就不再过多的解释了。
运行 demo
在 flagdemo 目录下执行 go build 命令编译 demo 生成可执行文件 flagdemo。下面我们通过运行 demo 程序来了解 pflag 包命令行参数的语法特点。
布尔类型的参数
布尔类型的参数有下面几种写法
--flag // 等同于 --flag=true
--flag=value
--flag value // 这种写法只有在没有设置默认值时才生效

NoOptDefVal 用法
pflag 包支持通过简便的方式为参数设置默认值之外的值,实现方式为设置参数的 NoOptDefVal 属性:
var cliAge = flag.IntP("age", "a",, "Input Your Age")
flag.Lookup("age").NoOptDefVal = ""
下面是传递参数的方式和参数最终的取值:
Parsed Arguments Resulting Value
--age= cliAge=
--age cliAge=
[nothing] cliAge=

shorthand
与 flag 包不同,在 pflag 包中,选项名称前面的 -- 和 - 是不一样的。- 表示 shorthand,-- 表示完整的选项名称。
除了最后一个 shorthand,其它的 shorthand 都必须是布尔类型的参数或者是具有默认值的参数。
所以对于布尔类型的参数和设置了 NoOptDefVal 的参数可以写成下面的形式:
-o
-o=true
// 注意,下面的写法是不正确的
-o true
非布尔类型的参数和没有设置 NoOptDefVal 的参数的写法如下:
-g female
-g=female
-gfemale
日常的使用中一般会混合上面的两类规则:
-aon "jack"
-aon="jack"
-aon"jack"
-aonjack
-oa=
注意 -- 后面的参数不会被解析:
-oa= -- -gfemale

标准化参数的名称
如果我们创建了名称为 --des-detail 的参数,但是用户却在传参时写成了 --des_detail 或 --des.detail 会怎么样?默认情况下程序会报错退出,但是我们可以通过 pflag 提供的 SetNormalizeFunc 功能轻松的解决这个问题:
func wordSepNormalizeFunc(f *flag.FlagSet, name string) flag.NormalizedName {
from := []string{"-", "_"}
to := "."
for _, sep := range from {
name = strings.Replace(name, sep, to, -)
}
return flag.NormalizedName(name)
}
flag.CommandLine.SetNormalizeFunc(wordSepNormalizeFunc)
下面的写法也能正确设置参数了:
--des_detail="person detail"

把参数标记为即将废弃
在程序的不断升级中添加新的参数和废弃旧的参数都是常见的用例,pflag 包对废弃参数也提供了很好的支持。通过 MarkDeprecated 和 MarkShorthandDeprecated 方法可以分别把参数及其 shorthand 标记为废弃:
// 把 badflag 参数标记为即将废弃的,请用户使用 des-detail 参数
flag.CommandLine.MarkDeprecated("badflag", "please use --des-detail instead")
// 把 badflag 参数的 shorthand 标记为即将废弃的,请用户使用 des-detail 的 shorthand 参数
flag.CommandLine.MarkShorthandDeprecated("badflag", "please use -d instead")

在帮助文档中隐藏参数
pflag 包还支持在参数说明中隐藏参数的功能:
// 在帮助文档中隐藏参数 badflag
flag.CommandLine.MarkHidden("badflag")

看,帮助文档中没有显示 badflag 的信息。其实在把参数标记为废弃时,同时也会设置隐藏参数。
总结
正如本文中介绍的,pflag 包提供了很多非常棒的功能,这些功能方便了应用程序的开发者。因此越来越多的使用者抛弃标准库中的 flag 包转而使用 pflag 包解析命令行参数。
参考:
github spf13/pflag
Golang之使用Flag和Pflag
Golang命令行参数解析库源码分析:flag VS pflag
Golang : pflag 包简介的更多相关文章
- Golang : cobra 包简介
Cobra 是一个 Golang 包,它提供了简单的接口来创建命令行程序.同时,Cobra 也是一个应用程序,用来生成应用框架,从而开发以 Cobra 为基础的应用.本文的演示环境为 ubuntu 1 ...
- Golang : flag 包简介
在 Golang 程序中有很多种方法来处理命令行参数.简单的情况下可以不使用任何库,直接处理 os.Args:其实 Golang 的标准库提供了 flag 包来处理命令行参数:还有第三方提供的处理命令 ...
- Golang : cobra 包解析
笔者在<Golang : cobra 包简介>一文中简要的介绍了 cobra 包及其基本的用法,本文我们从代码的角度来了解下 cobra 的核心逻辑. Command 结构体 Comman ...
- GO语言的进阶之路-go的程序结构以及包简介
GO语言的进阶之路-go的程序结构以及包简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑,编译和运行 A,编辑 Go程序使用UTF-8编码的纯Unicode文本编写.大 ...
- Golang Vendor 包管理工具 glide 使用教程
Glide 是 Golang 的 Vendor 包管理器,方便你管理 vendor 和 verdor 包.类似 Java 的 Maven,PHP 的 Composer. Github:https:// ...
- 【转】commons-lang.jar包简介
转自:http://zhidao.baidu.com/share/71b48e6b3e1b1dc73fe705604b9c7584.html 1.下载jar包 包官方下载地址:http://commo ...
- Golang fmt包使用小技巧
h1 { margin-top: 0.6cm; margin-bottom: 0.58cm; direction: ltr; color: #000000; line-height: 200%; te ...
- Hadoop2.0源码包简介
Hadoop2.0源码包简介 1.解压源码包: 2.目录结构: hadoop-common-project:Hadoop基础库所在目录,如RPC.Metrics.Counter等.包含了其它所有模块可 ...
- Golang Vendor 包机制 及 注意事项
现在的 Go 版本是 1.8,早在 1.5 时期,就有了 Vendor 包机制,详情可查看博文:“理解 Go 1.5 vendor”. 遇到的问题 个人在使用 Glide 管理 Vendor 包时(附 ...
随机推荐
- Leslie Lamport
http://lamport.azurewebsites.net/pubs/pubs.html paper
- 【shell】获取第10+个位置参数
转载自:http://www.cnblogs.com/sheldonxu/archive/2012/06/25/2560770.html 在Shell脚本中,可以用$n的方式获取第n个参数,例如,一个 ...
- Java for LeetCode 113 Path Sum II
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- Java for LeetCode 084 Largest Rectangle in Histogram【HARD】
For example, Given height = [2,1,5,6,2,3], return 10. 解题思路: 参考Problem H: Largest Rectangle in a Hist ...
- turbolink 造成 link_to异常
link_to 点击之后不刷新不加载文件 send_file 只能在浏览器中打开,而不能下载 解决方法:注释gem turbolink,application.js 中移除turbolink
- python优缺点小结
优点: 1.语言简洁优美 例如去除了大括号,写法简单,写法更接近于英语,其他语言几十上百行的代码,十来行就能解决,而且还好看 2.跨平台,window.linux.mac通用 3.排行高,社区完善 ...
- Redmine后台修改admin密码
Redmine后台修改admin密码 进入redmine安装目录,假设redmine安装在/var/www/html/redmine/目录下. cd /var/www/html/redmine/scr ...
- hihocoder #1040 矩形判断(计算几何问题 给8个点的坐标,能否成为一个矩形 【模板思路】)
#1040 : 矩形判断 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 给出平面上4条线段,判断这4条线段是否恰好围成一个面积大于0的矩形. 输入 输入第一行是一个整数T ...
- 为什么在实际的 kaggle 比赛中 gbdt 和 random forest 效果非常好?
https://www.zhihu.com/question/51818176/answer/127637712
- Linux-Yum服务器搭建
Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从指定的服务器自动下载 ...