1

呼び出される関数の内部から関数が呼び出される出力引数の数をチェックする方法は Python にありますか?

例えば:

a,b = Fun() #-> number of output arguments would be 2
a,b,c = Fun() #-> number of output arguments would be 3

matlab では、これはnargout を使用して行われます。これを行う「通常の方法」は、不要な値を _ 変数にアンパックすることです。

def f():
    return 1, 2, 3

_, _, x = f()

私が達成しようとしていることは単純です。いくつかの引数または2つのオブジェクトで呼び出された場合は単一のオブジェクトを返す関数があります。

def f(a,b=None):
    if b is None:
        return 1
    else:
        return 1,2

しかし、タプルのアンパックが起こらないように強制し、エラーを強制したいと思います。次に例を示します。

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.
4

2 に答える 2

2

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()
于 2013-05-10T20:09:42.737 に答える
1

Python 3 を使用している場合は、LH で拡張された iterable unpackingを使用できます。

>>> 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)

どちらの場合も、_be でNoneありrtr、be1または(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)
于 2013-05-10T20:29:22.277 に答える