Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python检查函数调用时的输出参数数量_Python_Matlab_Arguments_Return - Fatal编程技术网

Python检查函数调用时的输出参数数量

Python检查函数调用时的输出参数数量,python,matlab,arguments,return,Python,Matlab,Arguments,Return,python中有没有一种方法可以从被调用函数的内部检查调用函数的输出参数的数量 例如: a,b = Fun() #-> number of output arguments would be 2 a,b,c = Fun() #-> number of output arguments would be 3 x = f(a) #-> Fine x,y = f(a,b) #-> Fine x,y = f(a) #-> Will throw native error:

python中有没有一种方法可以从被调用函数的内部检查调用函数的输出参数的数量

例如:

a,b = Fun() #-> number of output arguments would be 2
a,b,c = Fun() #-> number of output arguments would be 3
x = f(a) #-> Fine
x,y = f(a,b) #-> Fine
x,y = f(a) #-> Will throw native error: ValueError: need more than Foo values to unpack
x = f(a,b) #-> Want to force this to throw an error and not default to the situation where x will be a tuple.
在matlab中,这将使用 我知道这样做的目的是将不需要的值解包到u变量:

def f():
    return 1, 2, 3

_, _, x = f()
我想做的很简单。我有一个函数,如果用一些参数调用,它将返回一个对象,否则将返回两个对象:

def f(a,b=None):
    if b is None:
        return 1
    else:
        return 1,2
但我想强制元组解包不发生,并强制出错,例如:

a,b = Fun() #-> number of output arguments would be 2
a,b,c = Fun() #-> number of output arguments would be 3
x = f(a) #-> Fine
x,y = f(a,b) #-> Fine
x,y = f(a) #-> Will throw native error: ValueError: need more than Foo values to unpack
x = f(a,b) #-> Want to force this to throw an error and not default to the situation where x will be a tuple.

正如Ashwini指出的,这似乎是可行的:

import inspect,dis

def expecting():
    """Return how many values the caller is expecting"""
    f = inspect.currentframe()
    f = f.f_back.f_back
    c = f.f_code
    i = f.f_lasti
    bytecode = c.co_code
    instruction = bytecode[i+3]
    if instruction == dis.opmap['UNPACK_SEQUENCE']:
        howmany = bytecode[i+4]
        return howmany
    elif instruction == dis.opmap['POP_TOP']:
        return 0
    return 1

def cleverfunc():
    howmany = expecting()
    if howmany == 0:
        print("return value discarded")
    if howmany == 2:
        return 1,2
    elif howmany == 3:
        return 1,2,3
    return 1

def test():
    cleverfunc()
    x = cleverfunc()
    print(x)
    x,y = cleverfunc()
    print(x,y)
    x,y,z = cleverfunc()
    print(x,y,z)

test()

如果使用Python 3,可以在左侧使用:

>>> def f(n):
...    return tuple(range(n))
... 
>>> f(3)
(0, 1, 2)
>>> a,b,*c=f(20)
>>> a
0
>>> b
1
>>> c
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
使用您的功能,您可以执行以下操作:

>>> def f(a,b=None):
...     if b is None:
...         return 1
...     else:
...         return 1,2
>>> rtr,*_=f(1),None
>>> rtr
1
>>> rtr,*_=f(1,True),None
>>> rtr
(1, 2)
在任何一种情况下,
\uuu
都将是
None
rtr
将是
1
(1,2)

您可能希望从f显式返回元组,以避免以后出现歧义:

>>> def f(a,b=None):
...    return (1,2) if b else (1,)
... 
>>> rtr,*_=f(1),None
>>> rtr
(1,)
>>> rtr,*_=f(1,True),None
>>> rtr
(1,2)
如果这样做的话--它也可以在Python 2X下工作:

Python 2.7:

>>> def f(a,b=None):
...    return (1,2) if b else (1,)
... 
>>> x,y=f(1),None
>>> x
(1,)
>>> x,y=f(1,True),None
>>> z
>>> x
(1, 2)

你可能想浏览几个月前的档案。有人建议添加一个独立于迭代器协议的“解包协议”,这将使类似的事情变得微不足道。IIRC,这个想法被否决了,但是在这个过程中有人提出了一些“今天Python中的黑客实现”。注意,这取决于字节码,字节码只保证存在于参考实现CPython中,在其他Python实现中可能不起作用。即使在CPython中,操作码及其语义也可以在功能发布之间更改,而无需事先通知。特别是,Python 3.6中所有操作码的指令大小都发生了变化。此外,这不能正确处理扩展解包的情况(例如,使用
a、*b、c=func()
),在这种情况下,您可能希望返回尽可能多的结果(或文档,说明您的函数不是以这种方式调用的)。