使用 Abseil 与直接调用 main()?

Sib*_*ing 9 python abseil absl-py

我一直在用香草

def main():
    # Do stuff


if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

但最近看到人们在做

from absl import app

def main(_):
    # Do things

if __name__ == '__main__':
    app.run(main)
Run Code Online (Sandbox Code Playgroud)

Abseil 提供了flags.FLAGS,但我一直在使用ArgumentParser,它工作得很好,所以 Abseil 在这方面没有胜利。

那么,为什么还要走绳降路线呢?

PS:Reddit上的相关讨论(并没有真正回答这个问题):https://www.reddit.com/r/Python/comments/euhl81/is_using_googles_abseil_library_worth_the/

小智 1

考虑一种设计模式,您在 cmd 行传递一个 json 文件(其中包含特定于站点的常量)作为 Python 脚本的输入。比如说,json 文件包含不可变常量,并且您希望以这种方式维护它。

您希望 json 文件内容中的常量可供项目中的所有模块使用。

实现此目的的一种方法是实现一个中央模块,将 json 反序列化为 Python 对象。ABSL 通过访问(通过FLAGS)中央模块中的输入文件,然后将其存储到类变量中,以便项目中的所有模块都可以使用它,来帮助您解决这个问题。

如果没有 ABSL,您需要首先在主模块中对输入文件进行 argparse,然后将其发送到中央模块。

其代码示例可能类似于 main.py

from centralmod import DeserializeClass
import centralmod
from absl import flags
from absl import app

_JSON_FILE = flags.DEFINE_string("json_file", None, "Constants", short_name='j', required=True)


def scenario():
    import someothermodule
    someothermodule.do_something()


def populate_globalvar():
    centralmod.populate_somevar()
    deserialized_data = DeserializeClass.somevar


def main(argv):
    populate_globalvar()
    scenario()


if __name__ == '__main__':
    app.run(main)
Run Code Online (Sandbox Code Playgroud)

centralmod.py

from absl import flags
import json

FLAGS = flags.FLAGS


class DeserializeClass:
    @classmethod
    def get_value(cls, key):
        return DeserializeClass.somevar[key]


def populate_somevar():
    with open(FLAGS.json_file) as json_constants_fh:
        deserialized_data = json.load(json_constants_fh)
    setattr(DeserializeClass, 'somevar', deserialized_data)
Run Code Online (Sandbox Code Playgroud)

someothermod.py

from centralmod import DeserializeClass
site_specific_consts = DeserializeClass.somevar

def do_something():
    print(f"\nScenario: Testing. The site-specific constants are:\n{site_specific_consts}")
    print(f"the value of key ssh_key_file is {DeserializeClass.get_value('ssh_key_file')}")
    print(f"the value of key nodes is {DeserializeClass.get_value('nodes')}")
Run Code Online (Sandbox Code Playgroud)