Abseil Python Flags 库(abseil-py-flags)的使用

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: gflags-py介绍,abseil-py flags介绍。

1. What:gflags-py的前世今生

1.1 什么是command line flags

command line flags,也就是命令行参数方式,是linux系统上,最常见的命令行参数方式。
例如,在wc -l中,-l就是一个命令行标志。
相比较其他的配置方式,简单清晰。
相比较xml,json的配置文件的复杂性,大多数小型程序,以及习惯linux开发环境的用户,使用命令行参数的非常多。

1.2 gflags做了什么

gflags是Google开源的一套命令行参数处理的开源库,包括C++的版本和Python版本。
和getopt()之类的库不同,flag的定义可以散布在各个源码中,而不用放在一起。一个源码文件可以定义一些它自己的flag,链接了该文件的应用都能使用这些flag。
这样就能非常方便地复用代码。如果不同的文件定义了相同的flag,链接时会报错。
gflags使用起来比getopt方便,但是不支持参数的简写(例如getopt支持--list缩写成-l,gflags不支持)。
c++版本gflags的地址是:gflags工程地址gflags文档地址

1.3 gflags-python的演变

python版本的gflags曾经是一个独立的代码项目,gflags-python,后来,被整合进入abseil-py仓库中,成为几个公共组件的一部分。
新的gflags-py文档地址

2. Why:为什么是gflags

在python使用命令行参数,通常有几个方式:argparse,sys。下面就分别举例子看下。

2.1 argparse的使用

argparse模块是Python自带的处理命令行参数的模块,它是Python标准库的一部分。
argparse使用主要有四个步骤:

  • 导入argparse包
  • 创建 ArgumentParser() 参数对象
  • 调用 add_argument() 方法往参数对象中添加参数
  • 使用 parse_args() 解析添加参数的参数对象,获得解析对象
  • 程序其他部分,当需要使用命令行参数时,使用解析对象.参数获取
import argparse

def main():
    # 定义一个ArgumentParser实例:
    parser = argparse.ArgumentParser(
        prog='test', # 程序名
        description='Test.', # 描述
        epilog='Copyright(r), 2023' # 说明信息
    )

    # 定义参数:
    parser.add_argument('--host', default='localhost')
    # 定义参数必须为int类型:
    parser.add_argument('--port', default='3306', type=int)

    # 解析参数:
    args = parser.parse_args()

    # 打印参数:
    print(f'host = {args.host}')
    print(f'port = {args.port}')

if __name__ == '__main__':
    main()

2.2 sys的使用

sys的方式比较直接,就是按照linux程序的方式直接读取参数,全部当成字符串处理,没有变量的检查和定义,全部需要程序自己处理,没有约束和规则。

import sys

print(sys.argv)
source = sys.argv[1]
target = sys.argv[2]

# TODO:

2.3 gflags的使用简介

gflags,这里指的是gflags-py,使用起来就非常简单,这里只是举一个简单的例子,详细的使用在后面介绍:

from absl import app
from absl import flags
FLAGS = flags.FLAGS


flags.DEFINE_string('host', 'localhost', 'input host')
flags.DEFINE_integer('port', 3306, 'input port')

def main(argv):
    print(f'host = {FLAGS.host}')
    print(f'port = {FLAGS.port}')

if __name__ == '__main__':
    app.run(main)

可以看到,gflags做了很好的封装,定义和类型限制很直接,使用也比较方便,而且支持list,enum等多种类型的定义,支持配置写在单独的文件中直接加载,或者多个文件中互相引用加载。
这是高等级的封装,也是我们选用这个库的主要原因。

3. How:基本的使用

3.1 基本的使用

可以先看官方文档的一个例子:

from absl import app
from absl import flags

FLAGS = flags.FLAGS

# Flag names are globally defined!  So in general, we need to be
# careful to pick names that are unlikely to be used by other libraries.
# If there is a conflict, we'll get an error at import time.
flags.DEFINE_string('name', 'Jane Random', 'Your name.')
flags.DEFINE_integer('age', None, 'Your age in years.', lower_bound=0)
flags.DEFINE_boolean('debug', False, 'Produces debugging output.')
flags.DEFINE_enum('job', 'running', ['running', 'stopped'], 'Job status.')


def main(argv):
    if FLAGS.debug:
        print('non-flag arguments:', argv)
        print('Happy Birthday', FLAGS.name)
    if FLAGS.age is not None:
        print('You are %d years old, and your job is %s' % (FLAGS.age, FLAGS.job))


if __name__ == '__main__':
    app.run(main)

上面代码中,flags.DEFINE_**是定义不同类型的参数配置。
每个参数至少需要三个配置:第一个参数是配置名称,第二个参数是配置的默认值,第三个参数是注释。
还可以有更多的参数,分别对应更高级的功能,下面会详细介绍。
FLAGS.xx是代码中访问定义配置的方式。
需要注意的是,需要首先显示的执行app.run(main),这样才能把参数详细的解析。这行是必不可少的。

3.2 多种类型支持

gflags支持多种参数类型:

  1. DEFINE_string:字符串类型
  2. DEFINE_bool:布尔类型
    • 对于这种类型,推荐在参数配置时,使用--myflag来配置True,使用--nomyflag来配置为False。
    • --myflag=true and --myflag=false 这种方式配置也是可以的,但是不推荐。
  3. DEFINE_float:浮点类型
    • 这中类型在定义是支持额外的参数lower_bound和upper_bound。如果超过这个范围,会抛出FlagError异常。
    • lower_bound:最小的限制
    • upper_bound:最大的限制
  4. DEFINE_integer:整数类型
    • 支持额外的lower_bound和upper_bound参数。
  5. DEFINE_enum:枚举类型
    • 约束传入的字符串是一个限制的内容列表内,如果不在限制的列表,会抛出异常,如果是限制内的字符串,配置就会设置为这个字符串。
    • flags.DEFINE_enum('job', 'running', ['running', 'stopped'], 'Job status.') 这里面,第一个参数是配置名称,第二个参数是配置的默认值,第三个参数是配置的限制值列表。
  6. DEFINE_list:列表类型(逗号)
    • 输入为使用逗号分隔的字符串,会转化为python的list变量。
    • 举例:--myspacesepflag "foo,bar,baz"
  7. DEFINE_spaceseplist:列表类型(空格)
    • 输入为使用空格分隔的字符串,会转化为python的list变量。
    • 举例:--myspacesepflag "foo bar baz"
  8. DEFINE_multi_string:多行字符串类型
    • 支持配置多行字符串的参数,返回一个list变量。
    • 返回的是一个list,哪怕只配置了一行。
  9. DEFINE_multi_integer
    • 支持配置多行整数的参数,返回一个list变量。
    • 返回的是一个list,哪怕只配置了一行。
  10. DEFINE_multi_enum
    • 支持配置多行枚举字符串类型的参数,返回一个list变量。
    • 返回的是一个list,哪怕只配置了一行。

DEFINEmulti** 定义和使用举例:

# 配置定义
from absl import flags

flags.DEFINE_multi_string(
  'gin_file', None, 'List of paths to the config files.')
flags.DEFINE_multi_string(
  'gin_param', None, 'Newline separated list of Gin parameter bindings.')
# 配置使用方式
.../xx_bin \
  --gin_file=$CONFIGS_PATH/cartpole_balance.gin \
  --gin_file=$CONFIGS_PATH/base_dqn.gin \
  --gin_file=$CONFIGS_PATH/eval.gin \
  --gin_param='evaluate.num_episodes_eval = 10' \
  --gin_param='evaluate.generate_videos = False' \
  --gin_param='evaluate.eval_interval_secs = 60'

3.3 配置文件支持

可以使用一个文件,放入所有配置的具体配置,然后通过一个特殊的配置--flagfile=filename来加载这个配置文件。
在配置文件中,#和//都表示注释。
配置文件中,可以递归使用--flagfile=A来引用。
所有的--flagfile都是依据当前工作目录,和引入的配置文件目录无关。

3.4 一些工程的配置定义例子

deepspeech
tensorflow


(作者信息)
数字老K
quantgalaxy@outlook.com
欢迎交流

目录
相关文章
|
26天前
|
XML JSON 数据库
Python的标准库
Python的标准库
163 77
|
2月前
|
调度 开发者 Python
Python中的异步编程:理解asyncio库
在Python的世界里,异步编程是一种高效处理I/O密集型任务的方法。本文将深入探讨Python的asyncio库,它是实现异步编程的核心。我们将从asyncio的基本概念出发,逐步解析事件循环、协程、任务和期货的概念,并通过实例展示如何使用asyncio来编写异步代码。不同于传统的同步编程,异步编程能够让程序在等待I/O操作完成时释放资源去处理其他任务,从而提高程序的整体效率和响应速度。
|
2月前
|
数据采集 存储 数据挖掘
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第27天】在数据分析领域,Python的Pandas库因其强大的数据处理能力而备受青睐。本文介绍了Pandas在数据导入、清洗、转换、聚合、时间序列分析和数据合并等方面的高效技巧,帮助数据分析师快速处理复杂数据集,提高工作效率。
85 0
|
2月前
|
机器学习/深度学习 算法 数据挖掘
数据分析的 10 个最佳 Python 库
数据分析的 10 个最佳 Python 库
102 4
数据分析的 10 个最佳 Python 库
|
27天前
|
XML JSON 数据库
Python的标准库
Python的标准库
48 11
|
2月前
|
人工智能 API 开发工具
aisuite:吴恩达发布开源Python库,一个接口调用多个大模型
吴恩达发布的开源Python库aisuite,提供了一个统一的接口来调用多个大型语言模型(LLM)服务。支持包括OpenAI、Anthropic、Azure等在内的11个模型平台,简化了多模型管理和测试的工作,促进了人工智能技术的应用和发展。
134 1
aisuite:吴恩达发布开源Python库,一个接口调用多个大模型
|
2月前
|
XML 存储 数据库
Python中的xmltodict库
xmltodict是Python中用于处理XML数据的强大库,可将XML数据与Python字典相互转换,适用于Web服务、配置文件读取及数据转换等场景。通过`parse`和`unparse`函数,轻松实现XML与字典间的转换,支持复杂结构和属性处理,并能有效管理错误。此外,还提供了实战案例,展示如何从XML配置文件中读取数据库连接信息并使用。
Python中的xmltodict库
|
27天前
|
数据可视化 Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
通过这些思维导图和分析说明表,您可以更直观地理解和选择适合的数据可视化图表类型,帮助更有效地展示和分析数据。
66 8
|
2月前
|
存储 人工智能 搜索推荐
Memoripy:支持 AI 应用上下文感知的记忆管理 Python 库
Memoripy 是一个 Python 库,用于管理 AI 应用中的上下文感知记忆,支持短期和长期存储,兼容 OpenAI 和 Ollama API。
101 6
Memoripy:支持 AI 应用上下文感知的记忆管理 Python 库
|
1月前
|
安全 API 文件存储
Yagmail邮件发送库:如何用Python实现自动化邮件营销?
本文详细介绍了如何使用Yagmail库实现自动化邮件营销。Yagmail是一个简洁强大的Python库,能简化邮件发送流程,支持文本、HTML邮件及附件发送,适用于数字营销场景。文章涵盖了Yagmail的基本使用、高级功能、案例分析及最佳实践,帮助读者轻松上手。
35 4