簡體   English   中英

如何按功能返回* args,** kwargs

[英]How to return *args, **kwargs by function

帶參數列表和關鍵字參數的簡單函數:

def foo(*args, **kwargs):
    print(args, kwargs)

我可以按如下方式調用此函數

foo('foo', 'bar', 'baz', hoge='H', fuga='F')

要么

l = ['foo', 'bar']
kw = {'hoge': 'H', 'fuga': 'F'}
foo(*l, **kw)

問題 :我可以通過其他函數傳遞參數嗎?

foo(produce_arg())

我正在使用Click https://palletsprojects.com/p/click/編寫CLI腳本。 幾個子命令采用相同的選項:

@click.group()
def cli():
    pass

@cli.command()
@cli.option('--target', type=str, ...)
@cli.option('--exec', is_flag=True, ...)
...
def foo():
    pass

@cli.command()
@cli.option('--target', type=str, ...)
...
def bar():
    pass

@cli.command()
@cli.option('--exec', is_flag=True, ...)
...
def baz():
    pass

...

我認為這不是DRY,所以我想寫如下:

def definition_of(optname):
    # so magical code!

@click.group()
def cli():
    pass

@cli.command()
@cli.option(definition_of('target'))
@cli.option(definition_of('exec'))
...
def foo():
    pass

@cli.command()
@cli.option(definition_of('target'))
...
def bar():
    pass

@cli.command()
@cli.option(definition_of('exec'))
...
def baz():
    pass

...

有任何想法嗎?

直接解決您的問題:是的,您可以通過另一個函數傳遞參數:

a, k = produce_arg()
foo(*a, **k)

這個過程可以“隱藏”,在某種程度上:

def pass_a_k(func, ak):
    return func(*ak[0], **ak[1])
pass_a_k(foo, produce_arg())

將是一種方法,

def pass_a_k(func, a, k):
    return func(*a, **k)
pass_a_k(foo, *produce_arg())

會有一個稍微不同的方法。

兩者都使用輔助函數來調用目標函數。

def pass_a_k(func, a, k):
    return func(*a, **k)
def adapt_a_k(func):
    # here, maybe fool around with functools.wraps etc.
    return lambda a, k: func(*a, **k)
adapt_a_k(foo)(*produce_arg())

(或其各自的對應方)將是另一種方法。 在這里,如果您需要更頻繁地保持“適應”功能將是有幫助的。

在你的例子中,那可能是

cli_option_a_k = adapt_a_k(cli.option)

@cli_option_a_k(*definition_of('target'))
@cli_option_a_k(*definition_of('exec'))
...
def foo():
    pass

甚至

cli_option_by_optname = lambda optname: adapt_a_k(cli.option)(*definition_of(optname))
cli_option_by_optname = lambda optname: pass_a_k(cli.option, *definition_of(optname))

@cli_option_by_optname('target')
@cli_option_by_optname('exec')
...
def foo():
    pass

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM