简体   繁体   English

在 Python 中将多个关键字参数从外部函数传递到内部函数?

[英]relay multiple keyword arguments from outer function to inner functions in Python?

I am trying to pass arguments to an outer function that then relays them to one or more inner functions.我试图将参数传递给一个外部函数,然后将它们中继到一个或多个内部函数。 The closest I've come to achieving this:我最接近实现这一目标的是:

def multiply(number, factor=1):
    return number*factor

def add(number, to_add=0):
    return number+to_add

def multiply_add(number, *args):
    return add(multiply(number, *args[0]), *args[1])

multiply_add(5, [3], [200])
Out[]: 215

This solution is impractical in a few ways: 1) The user has to know the order in which to pass the arguments, without using keywords;这个解决方案在几个方面是不切实际的:1) 用户必须知道传递参数的顺序,而不使用关键字; and 2) These arguments have to be iterables for some reason, otherwise get "TypeError: multiply() argument after * must be an iterable, not int" .和 2) 由于某种原因,这些参数必须是可迭代的,否则"TypeError: multiply() argument after * must be an iterable, not int"得到"TypeError: multiply() argument after * must be an iterable, not int"

My question: how to rewrite multiply_add() so the following works?我的问题:如何重写multiply_add()以便以下工作? :

multiply_add(5, factor=3, to_add=200)

PS I've seen a working example of this with Seaborn calling additional Matplotlib arguments. PS 我已经看到了一个关于 Seaborn 调用额外 Matplotlib 参数的工作示例。 For example, making the dot size equal to 25:例如,使点大小等于 25:

sns.jointplot(x='A', y='B', data=df, kind='reg', scatter_kws={'s': 25})

Something in this form would be great too.这种形式的东西也会很棒。

Ok, I figured out how to do this offline.好的,我想出了如何离线执行此操作。 There are at least two ways.至少有两种方式。

FIRST WAY: slap **kwargs absolutely everywhere第一种方式:绝对无处不在的**kwargs

def multiply(number, factor=1, **kwargs):
    return number*factor

def add(number, to_add=0, **kwargs):
    return number+to_add

def multiply_add(number, **kwargs):
    return add(multiply(number, **kwargs), **kwargs)

multiply_add(5, to_add=200, factor=3)

Note that argument order doesn't matter here.请注意,参数顺序在这里无关紧要。

SECOND WAY: specify different sets of **kwargs and pass them in dict form (my preferred)第二种方式:指定不同的**kwargs集并以 dict 形式传递它们(我的首选)

def multiply(number, factor=1):
    return number*factor

def add(number, to_add=0):
    return number+to_add

def multiply_add(number, kwargs_multiply, kwargs_add):
    return add(multiply(number, **kwargs_multiply), **kwargs_add)

multiply_add(5, {'factor':3}, {'to_add':200})

Note that argument order DOES matter here: the multiply() arguments need to be specified before the add() arguments.请注意,参数顺序在这里很重要: multiply()参数需要在add()参数之前指定。

This is not much beautiful code, but I think it does what you want right ?这不是很多漂亮的代码,但我认为它可以满足您的需求,对吗?

    1 def multiply(number, factor=1.0):
    2     return number*factor
    3 
    4 def add(number, to_add=0):
    5     return number+to_add
    6 
    7 def multiply_add(number, **kwargs):
    8     factor = kwargs.get("factor")
    9     to_add = kwargs.get("to_add")
   11     if to_add and factor:
   12         return add(multiply(number, factor), to_add)
   13     elif to_add:
   14         return add(multiply(number), to_add)
   15     elif factor:
   16         return add(multiply(number, factor))

Maybe you prefer:也许你更喜欢:

  1 def multiply(number, factor=1.0):
  2     if factor == None:
  3         factor=1.0
  4     return number*factor
  5 
  6 def add(number, to_add=0):
  7     if to_add == None:
  8        to_add=0
  9     return number+to_add
 10 
 11 def multiply_add(number, **kwargs):
 12     factor = kwargs.get("factor")
 13     to_add = kwargs.get("to_add")
 14     return add(multiply(number, factor), to_add)
 15 print multiply_add(30)
 16 print multiply_add(30, to_add=2)
 17 print multiply_add(30, to_add=25)
 18 print multiply_add(30, factor=8)
 19 print multiply_add(30, factor=2, to_add=6)

These answers didn't help me much, but I was looking for something else anyway.这些答案对我没有多大帮助,但无论如何我都在寻找其他东西。 Since I've figured it out, I thought I might post the answer here, for someone who may get here the same way I did.既然我已经弄清楚了,我想我可以在这里发布答案,对于那些可能以与我相同的方式到达这里的人。

In my case I wanted an outer function that would take my inner function as an argument and my inner function would have other arguments, but the inner function along with it's arguments could be different every time.在我的情况下,我想要一个外部函数,它将我的内部函数作为参数,而我的内部函数会有其他参数,但内部函数及其参数每次都可能不同。

Granted the solution I found is so easy, probably everyone knows it.当然,我找到的解决方案非常简单,可能每个人都知道。

So my outer function times the one time execution of the inner function and print out a pretty output:所以我的外部函数乘以内部函数的一次执行并打印出一个漂亮的输出:

def timeFun(function):
  t_start = perf_counter()
  print("---\nResult: ", function, "\nExecution time: ", perf_counter() - t_start, sep="")

Now for the sake of simplicity my inner function is such, that it's pointless to time it:现在为了简单起见,我的内部功能是这样的,计时是没有意义的:

def sumTogether(*args):
  return sum(args)

Now you simply call the function like this:现在您只需像这样调用函数:

timeFun(sumTogether(1, 2, 3, 4))

And the output is:输出是:

---     
Result: 10
Execution time: 7.99999999995249e-07

Also:还有:

def time(function):
  t_start = perf_counter()
  print("---\nResult: ", function, "\nExecution time: ", perf_counter() - t_start, sep="")

def sumTogether(*args, just_for_kicks=5):
  return sum(args) + just_for_kicks

time(sumTogether(1, 2, 3, 4, just_for_kicks=10))

Output:输出:

---     
Result: 20
Execution time: 8.999999999981245e-07

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

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