简体   繁体   English

拆分 python 单击函数之间的选项

[英]Splitting python click options betwen functions

My codebase has multiple scripts, say sc1.py and sc2.py.我的代码库有多个脚本,比如 sc1.py 和 sc2.py。 Their code looks like this (just replace 1 for 2 to imagine what the other is like):他们的代码如下所示(只需将 1 替换为 2 即可想象另一个是什么样子):

@click.command()
@click.option(--op1, default="def1", required=True)
def sc1(op1):
    pass

if __name__ == "__main__":
    sc1()

What I want to do is write a wrapper that handles concerns like loading the config file (and handling missing ones appropriately), configuring the logger, etc.我想做的是编写一个包装器来处理加载配置文件(并适当处理丢失的配置文件)、配置记录器等问题。

The logger, as an example, requires some options, eg the log level, and this option doesn't appear in any of the existing scripts.例如,记录器需要一些选项,例如日志级别,而这个选项不会出现在任何现有脚本中。 I'd like to handle it at the wrapper level (since the wrapper will deal with common concerns like log configuration).我想在包装器级别处理它(因为包装器将处理日志配置等常见问题)。

That is what the wrapper might look like:这就是包装器的样子:

@click.command()
@click.option(--level, default=INFO, required=False)
def wrapper(level, wrapped_main_function):
   # use level to setup logger basic config.
   wrapped_main_function()

Then I would modify the "main" in the scripts (sc1.py, sc2.py etc):然后我会修改脚本中的“main”(sc1.py、sc2.py 等):

from wrap_module import wrapper

@click.command()
@click.option(--op1, default="def1", required=True)
def sc1(op1):
    pass

if __name__ == "__main__":
    wrapper(???, sc1)

Put into words I am trying to split the options between two functions, say wrapper and sc1, and have wrapper deal with its own dedicated options and then call sc1, forwarding the remaining command line options.换句话说,我试图在两个函数之间拆分选项,比如 wrapper 和 sc1,并让 wrapper 处理它自己的专用选项,然后调用 sc1,转发剩余的命令行选项。 All while wrapper is not aware of what options those might be, since the whole point is to write something generic that can be used for all the scripts and having wrapper deal with the commonalities. wrapper 并不知道这些可能是什么选项,因为重点是编写一些通用的东西,可以用于所有脚本并让 wrapper 处理共性。

The command line should look something like:命令行应类似于:

python sc.py --op1 something --level debug

I can't figure out the right syntax to do what I want.我想不出正确的语法来做我想做的事。

I think you can get close to what you want with a slightly different approach.我认为您可以通过稍微不同的方法来接近您想要的东西。 First, we have the following in common.py :首先,我们在common.py中有以下内容:

import click


def add_common_options(func):
    func = click.option("--level")(func)
    return func


def handle_common_options(level):
    print("log level is", level)

And then in sc1.py , we have:然后在sc1.py中,我们有:

import click
from common import add_common_options, handle_common_options


@click.command()
@click.option("--op1")
@add_common_options
def sc1(op1, **common_options):
    handle_common_options(**common_options)
    print("op1 is", op1)


if __name__ == "__main__":
    sc1()

(With sc2.py implemented in a similar fashion.) (以类似的方式实现sc2.py

This gets you the behavior you want.这会让你得到你想要的行为。 The help output for sc1.py looks like: sc1.py 的帮助sc1.py如下所示:

Usage: sc1.py [OPTIONS]

Options:
  --op1 TEXT
  --level TEXT
  --help        Show this message and exit.

And you can run a command line like this:您可以像这样运行命令行:

$ python sc1.py --op1 foo --level info
log level is info
op1 is foo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM