[英]Python distinguish between returned tuple and multiple values
I want to write a wrapper function which call one function and pass the results to another function. 我想编写一个包装器函数,该函数调用一个函数并将结果传递给另一个函数。 The arguments and return types of the functions are the same, but I have problem with returning lists and multiple values.
函数的参数和返回类型相同,但是返回列表和多个值存在问题。
def foo():
return 1,2
def bar():
return (1,2)
def foo2(a,b):
print(a,b)
def bar2(p):
a,b=p
print(a,b)
def wrapper(func,func2):
a=func()
func2(a)
wrapper(bar,bar2)
wrapper(foo,foo2)
I am searching for a syntax which works with both function pairs to use it in my wrapper code. 我正在寻找一种可以在两个包装对中使用的语法,以便在包装代码中使用它。
EDIT: The definitions of at least foo2 and bar2 should stay this way. 编辑:至少foo2和bar2的定义应保持这种方式。 Assume that they are from an external library.
假设它们来自外部库。
There is no distinction. 没有区别。
return 1,2
returns a tuple. return 1,2
返回一个元组。 Parentheses do not define a tuple; 括号没有定义元组; the comma does.
逗号。
foo
and bar
are identical. foo
和bar
相同。
As I overlooked until JacobIRR's comment, your problem is that you need to pass an actual tuple, not the unpacked values from a tuple, to bar2
: 正如我在JacobIRR的评论之前一直忽略的那样,您的问题是,您需要将实际的元组而不是从元组中解包的值传递给
bar2
:
a = foo()
foo2(*a)
a = bar()
bar2(a)
I don't necessarily agree with the design, but following your requirements in the comments (the function definitions can't change), you can write a wrapper that tries to execute each version (packed vs. unpacked) since it sounds like you might not know what the function expects. 我不一定同意这种设计,但是按照注释中的要求(函数定义不能更改),您可以编写一个包装程序来尝试执行每个版本(打包与未打包),因为听起来像您可能不知道该功能期望什么。 The wrapper written below,
argfixer
, does exactly that. 下面写的包装程序
argfixer
正是这样做的。
def argfixer(func):
def wrapper(arg):
try:
return func(arg)
except TypeError:
return func(*arg)
return wrapper
def foo():
return 1,2
def bar():
return (1,2)
@argfixer
def foo2(a,b):
print(a,b)
@argfixer
def bar2(p):
a,b=p
print(a,b)
a = foo()
b = bar()
foo2(a)
foo2(b)
bar2(a)
bar2(b)
However, if you aren't able to put the @argfixer
on the line before the function definitions, you could alternatively wrap them like this in your own script before calling them: 但是,如果您不能将
@argfixer
放在函数定义之前的行上,则可以在调用它们之前将其像这样包装在您自己的脚本中:
foo2 = argfixer(foo2)
bar2 = argfixer(bar2)
And as mentioned in previous comments/answers, return 1,2
and return (1,2)
are equivalent and both return a single tuple. 如前面的评论/答案中所述,
return 1,2
和return (1,2)
是等效的,并且都返回一个元组。
This code does not run because of arg
differences. 由于
arg
差异,此代码无法运行。 It runs if you use def foo2(*args):
and def bar2(*p):
. 如果您使用
def foo2(*args):
和def bar2(*p):
它将运行。
The return 1, 2
and return (1, 2)
are equivalent. return 1, 2
和return (1, 2)
是等效的。 The comma operator just creates a tuple, whether it is enclosed in parentheses or not. 逗号运算符仅创建一个元组,无论是否将其括在括号中。
All programming languages that I know of return a single value , so, since you want to return multiple, those values must be wrapped into a collection type, in this case, a tuple. 我所知道的所有编程语言都返回一个值 ,因此,由于要返回多个值 ,因此必须将这些值包装为一个集合类型,在这种情况下为元组。
The problem is in the way you call the second function. 问题在于您调用第二个函数的方式。 Make it
bar2(a)
instead of bar2(*a)
, which breaks the tuple into separate arguments. 将其设置为
bar2(a)
而不是bar2(*a)
,这会将元组分成单独的参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.