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
欢迎交流

目录
相关文章
|
6天前
|
调度 开发者 Python
Python中的异步编程:理解asyncio库
在Python的世界里,异步编程是一种高效处理I/O密集型任务的方法。本文将深入探讨Python的asyncio库,它是实现异步编程的核心。我们将从asyncio的基本概念出发,逐步解析事件循环、协程、任务和期货的概念,并通过实例展示如何使用asyncio来编写异步代码。不同于传统的同步编程,异步编程能够让程序在等待I/O操作完成时释放资源去处理其他任务,从而提高程序的整体效率和响应速度。
|
9天前
|
数据采集 存储 数据挖掘
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第27天】在数据分析领域,Python的Pandas库因其强大的数据处理能力而备受青睐。本文介绍了Pandas在数据导入、清洗、转换、聚合、时间序列分析和数据合并等方面的高效技巧,帮助数据分析师快速处理复杂数据集,提高工作效率。
33 0
|
2天前
|
数据库 Python
异步编程不再难!Python asyncio库实战,让你的代码流畅如丝!
在编程中,随着应用复杂度的提升,对并发和异步处理的需求日益增长。Python的asyncio库通过async和await关键字,简化了异步编程,使其变得流畅高效。本文将通过实战示例,介绍异步编程的基本概念、如何使用asyncio编写异步代码以及处理多个异步任务的方法,帮助你掌握异步编程技巧,提高代码性能。
11 4
|
2天前
|
API 数据处理 Python
探秘Python并发新世界:asyncio库,让你的代码并发更优雅!
在Python编程中,随着网络应用和数据处理需求的增长,并发编程变得愈发重要。asyncio库作为Python 3.4及以上版本的标准库,以其简洁的API和强大的异步编程能力,成为提升性能和优化资源利用的关键工具。本文介绍了asyncio的基本概念、异步函数的定义与使用、并发控制和资源管理等核心功能,通过具体示例展示了如何高效地编写并发代码。
11 2
|
7天前
|
数据采集 JSON 测试技术
Python爬虫神器requests库的使用
在现代编程中,网络请求是必不可少的部分。本文详细介绍 Python 的 requests 库,一个功能强大且易用的 HTTP 请求库。内容涵盖安装、基本功能(如发送 GET 和 POST 请求、设置请求头、处理响应)、高级功能(如会话管理和文件上传)以及实际应用场景。通过本文,你将全面掌握 requests 库的使用方法。🚀🌟
28 7
|
24天前
|
网络协议 数据库连接 Python
python知识点100篇系列(17)-替换requests的python库httpx
【10月更文挑战第4天】Requests 是基于 Python 开发的 HTTP 库,使用简单,功能强大。然而,随着 Python 3.6 的发布,出现了 Requests 的替代品 —— httpx。httpx 继承了 Requests 的所有特性,并增加了对异步请求的支持,支持 HTTP/1.1 和 HTTP/2,能够发送同步和异步请求,适用于 WSGI 和 ASGI 应用。安装使用 httpx 需要 Python 3.6 及以上版本,异步请求则需要 Python 3.8 及以上。httpx 提供了 Client 和 AsyncClient,分别用于优化同步和异步请求的性能。
python知识点100篇系列(17)-替换requests的python库httpx
|
8天前
|
机器学习/深度学习 数据采集 算法
Python机器学习:Scikit-learn库的高效使用技巧
【10月更文挑战第28天】Scikit-learn 是 Python 中最受欢迎的机器学习库之一,以其简洁的 API、丰富的算法和良好的文档支持而受到开发者喜爱。本文介绍了 Scikit-learn 的高效使用技巧,包括数据预处理(如使用 Pipeline 和 ColumnTransformer)、模型选择与评估(如交叉验证和 GridSearchCV)以及模型持久化(如使用 joblib)。通过这些技巧,你可以在机器学习项目中事半功倍。
19 3
|
11天前
|
数据采集 数据可视化 数据处理
如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`)
本文介绍了如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`),加载历史数据,计算均线和其他技术指标,实现交易逻辑,记录和可视化交易结果。示例代码展示了如何根据均线交叉和价格条件进行开仓、止损和止盈操作。实际应用时需注意数据质量、交易成本和风险管理。
31 5
|
10天前
|
存储 数据挖掘 数据处理
Python数据分析:Pandas库的高效数据处理技巧
【10月更文挑战第26天】Python 是数据分析领域的热门语言,Pandas 库以其高效的数据处理功能成为数据科学家的利器。本文介绍 Pandas 在数据读取、筛选、分组、转换和合并等方面的高效技巧,并通过示例代码展示其实际应用。
24 1
|
19天前
|
数据可视化 数据挖掘 Python
Seaborn 库创建吸引人的统计图表
【10月更文挑战第11天】本文介绍了如何使用 Seaborn 库创建多种统计图表,包括散点图、箱线图、直方图、线性回归图、热力图等。通过具体示例和代码,展示了 Seaborn 在数据可视化中的强大功能和灵活性,帮助读者更好地理解和应用这一工具。
32 3
下一篇
无影云桌面