简体   繁体   English

Python区分返回的元组和多个值

[英]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. foobar相同。

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,2return (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, 2return (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.

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