【问题标题】:Make a Python function that returns the same arguments as it receives创建一个 Python 函数,该函数返回与它接收到的参数相同的参数
【发布时间】:2021-07-20 19:53:35
【问题描述】:

在 Python 中编写一个函数以返回与它在运行时收到的完全相同的参数的正确方法是什么?

例如:

def pass_thru(*args, **kwargs):
    # do something non-destructive with *args & **kwargs
    return ??? <- somehow return *args & **kwargs

【问题讨论】:

  • 返回 args, kwargs ?
  • 显示示例输入和预期输出
  • 关键字参数不是一流的值,因此您无法确切地获得您传递的内容。 return *args, kwargs 可能是你能得到的最接近的。 (这是一个单元组,其第一个 n 元素是 n 位置参数,最后一个元素是由累积的关键字参数构造的 dict。)
  • 你做不到的。您可以编写 pass_thru(*pass_thru(...)) 以便外部调用获得相同的位置参数,但任何关键字参数都将作为单个 dict 接收,而不是键/值对的解压缩 dict
  • 函数组合对于 Python 函数没有明确定义。从数学上讲,所有函数都接受一个参数并返回一个值。 Python 函数不是数学函数。我曾经试图列举你可能尝试定义 Python 函数组合的所有方式;我想有5个。例如,如果g 返回一个元组,您希望组合是lambda x: f(g(x)) 还是lambda x: f(*g(x))?可能是任何一个,这取决于 f 的期望。

标签: python return variadic-functions


【解决方案1】:

考虑以下函数:

def a(*args, **kwargs):
    return args, kwargs

当我们调用函数时,返回的值是一个元组,首先包含另一个带有参数的元组,然后是一个带有关键字参数的字典:

b = a(1, 2, 3, a='foo')
print(b)

输出:((1, 2, 3), {'a': 'foo'})

print(b[0]) # Gives the args as a tuple
print(b[1]) # Gives the kwargs as a dictionary

【讨论】:

  • 我不确定这有什么帮助。从我的函数返回后,我想让堆栈保持与调用我的函数时相同的状态。
【解决方案2】:

问题在于您的参数只是一个值序列,而不是您可以操纵的值本身。关键字参数本身不是一等值(也就是说,a=3 不是一个值);它们纯粹是一种句法结构。

*** 参数让你成功了一半:

def pass_thru(*args, **kwargs):
    return *args, kwargs

然后

>>> pass_thru(1, 2, a=3)
(1, 2, {'a': 3})

但您不能简单地将其传递回pass_thru;你会得到不同的结果。

>>> pass_thru(pass_thru(1,2,a=3))
((1, 2, {'a': 3}), {})

你可以尝试解包元组:

>>> pass_thru(*pass_thru(1,2,a=3))
(1, 2, {'a': 3}, {})

但你真正需要的是解压字典。类似的东西

>>> *a, kw = pass_thru(1,2,a=3)
>>> pass_thru(*a, **kw)
(1, 2, {'a': 3})

据我所知,没有办法将最后一个示例组合成单个嵌套函数调用。

【讨论】:

  • 由于我们的项目限制,我使用的是 Python 3.6。在 3.6 中,如果我使用 return *a, **k IDE 抱怨:Python version 3.6 does not support unpacking without parentheses in return statements
  • 我从未建议过return *a, **k:这在任何版本的 Python 中都是语法错误(至少,到 3.9 为止)。 **k 仅适用于函数调用参数列表和字典推导,其中键/值对与所需目标之间存在已知映射。
  • 这是在你的例子中 - return *args, **kwargs,我只是把它缩短了。
  • 不,不是。 return *args, kwargsreturn *args, **kwargs 非常不同。前者返回一个元组;后者是语法错误。
  • 对不起,我的错!你在kwargs之前没有使用**
猜你喜欢
  • 1970-01-01
  • 2022-08-05
  • 1970-01-01
  • 2021-07-03
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多