【问题标题】:Pass function outputs as arguments to another function将函数输出作为参数传递给另一个函数
【发布时间】:2015-04-13 10:09:31
【问题描述】:

我需要将 Python 中函数的输出作为参数传递给另一个函数。唯一的问题是第一个函数返回一个元组,整个元组需要传递给第二个函数。

例如:

我有一个库函数:

def some_function(some_string, some_number):
    # does something
    return (text,id)

现在我想将从some_function 返回的textid 作为参数传递给另一个函数。问题是该函数还有其他参数。我还需要检索由some_stringnumber 的不同值生成的许多文本和ID。

根据满足的条件,我想调用另一个看起来像这样的函数

 if abcd:
     other_function(name,phone,**some_function("abcd","123")**,age)
 elif xyz:
     other_function(name,phone,**some_function("xyz","911")**,age)
 else:
     other_function(name,phone,**some_function("aaaa","000")**,age)

那么我应该用什么替换 some_function("abcd","123") 以便它扩展元组并将 textid 作为参数发送?

other_function 是这样定义的

def other_function(name, phone, text, id, age):
   ...
    return 

简单地将some_function("aaaa","000") 作为参数传递是否有效?


我问这个是因为我写了一个简单的代码来测试我的假设,它给了我一个空白的输出。

def f(id,string):
    return ("123", "hello")

def a(name, age, id, words, phone):
     print name + age + id + words + phone


def main():
    a("piyush", "23", f("12", "abc"), "123")

【问题讨论】:

  • 这不会给出空白输出,它会引发 TypeError。
  • @DanielRoseman per the OP's link below,看起来他们实际上并没有运行任何东西!你是对的,通过; a() takes exactly 5 arguments (4 given).

标签: python argument-passing function-calls


【解决方案1】:

您有两个选择*;要么先显式解压函数结果:

id, words = f('12', 'abc')
a('piyush', '23', id, words, '123')

或在对a 的调用中使用元组解包,并通过关键字提供最后一个参数:

a('piyush', '23', *f('12', 'abc'), phone='123')

如果此语法不熟悉,请参阅What does ** (double star) and * (star) do for parameters?


请注意,如果您尝试将phone 作为位置参数(而不是上面的关键字参数)来自f 的解压缩结果之后传递,即

a('piyush', '23', *f('12', 'abc'), '123')

你会得到SyntaxError: only named arguments may follow *expression* 解包后不能有位置参数,您必须将关键字用于任何其他参数。


* 除非你:

【讨论】:

  • 在你提到的第二种方法中,如果我用变量调用函数a而不是显式指定值怎么办?它会在像 a(student_name,student_age,*f('12','abc'),student_age) 这样的情况下工作吗
  • @Piyush 不,我已经用该信息更新了我的答案; * 解包后不能有位置参数,您必须为最后一个参数使用关键字。
  • @Piyush 但是,a(student_name, student_age, *f('12', 'abc'), age=student_age) 可以完美运行;问题不在于使用变量,只是在* 之后不能有额外的位置参数。
  • 感谢您的澄清
【解决方案2】:

您还可以更改签名中参数的顺序:

def a(name, age, id, words, phone):
     name = name
     age=age
     id=id
     words=words
     phone=phone
     print name+age+id+words+phone

a("piyush", "23", 123, *f("12","123"))
piyush23123123hello

这样你可以在调用函数时直接解包返回的值。 但是请注意,这会导致可读性非常差并且调试更加困难。

此外,如果您不想使用解包并更改调用函数的方法,您可以像这样更改代码:

def a(name, age, id_words, phone):
     name = name
     age=age
     id=id_words[0]
     words=id_words[1]
     phone=phone
     print name+age+id+words+phone

a("piyush", "23", f("12","123"), "123")
piyush23123hello123

这样做的好处是可以使所有函数调用保持原样。只有函数的内部工作会改变,签名不会改变。

【讨论】:

  • 我尝试在ideone 上运行它。我仍然得到一个空白输出。
  • 可以直接使用原始调用签名解包结果,只要对元组解包后的所有内容使用关键字参数。我同意它不适合调试,与在调用 a 之前显式命名返回值相比。
  • @jonrsharpe:您可以直接使用原始调用签名解包结果即使不使用元组解包之后的所有内容的关键字参数,只要您可能需要 Python 3.5。可悲的是,你可能不需要 Python 3.5,因为它甚至要到 5 个月后才能完成。 :)
  • @jonrsharpe 为了便于理解。如果我有两个这样的函数 f 和 g 都返回元组,那么它将如何工作?这个函数会运行还是我必须通过关键字提供参数。例如:a("piyush", *g("abc","zzz"), *f("12","123"))
  • @Piyush 为什么不试试看呢?
【解决方案3】:

假设你生活在未来,正确的做法是将元组解包到参数列表的中间,如下所示:

a('piyush', '23', *f('12', 'abc'), '123')

不幸的是,作为 OP 的你,可能不会生活在未来,所以这在很大程度上只对在 September 2015 之后找到这个答案的人有帮助(或者愿意在此之前需要 Python 的预发布版本) )。这个功能被添加为PEP 448,直到 Python 3.5 才加入(并且,截至 2015 年 4 月 13 日,主干中甚至还没有补丁——但如果你真的想危险地生活,你可以下载#2292 的最新补丁,将它应用到 repo 的本地分支,然后自己构建它......)。

所以,暂时,你必须伪造它,例如,jonrsharpe's answer

【讨论】:

    猜你喜欢
    • 2017-08-07
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多