Est-il possible d'invoquer une fonction Python avec le mauvais nombre d'arguments sans invoquer un TypeError?

StackOverflow https://stackoverflow.com/questions/933484

  •  06-09-2019
  •  | 
  •  

Question

Lorsque vous appelez une fonction avec le mauvais nombre d'arguments, ou avec un argument mot-clé qui n'est pas dans sa définition, vous obtenez un TypeError. Je voudrais un morceau de code pour prendre un rappel et invoquer des arguments variables, en fonction de ce que le rappel prend en charge. Une façon de le faire serait, pour une cb de rappel, utilisez cb.__code__.cb_argcount et cb.__code__.co_varnames, mais je plutôt abstraite en quelque chose comme apply, mais qui applique uniquement les arguments qui « correspondent ».

Par exemple:

 def foo(x,y,z):
   pass

 cleanvoke(foo, 1)         # should call foo(1, None, None)
 cleanvoke(foo, y=2)       # should call foo(None, 2, None)
 cleanvoke(foo, 1,2,3,4,5) # should call foo(1, 2, 3)
                           # etc.

Y at-il quelque chose comme ça déjà en Python, ou est-ce quelque chose que je devrais écrire à partir de zéro?

Était-ce utile?

La solution

Au lieu de creuser dans les détails vous-même, vous pouvez inspecter la signature de la fonction - vous voulez probablement inspect.getargspec(cb)

.

Exactement comment vous voulez utiliser cette information, et les args que vous avez, pour appeler la fonction « correctement », est pas tout à fait clair pour moi. Si l'on suppose pour simplifier que vous ne vous préoccupez args simples nommés et les valeurs que vous souhaitez passer sont dict d ...

args = inspect.getargspec(cb)[0]
cb( **dict((a,d.get(a)) for a in args) )

Peut-être que vous voulez quelque chose de fantaisie, et peut élaborer exactement quoi?

Autres conseils

peut-être?

def fnVariableArgLength(*args, **kwargs):
    """
    - args is a list of non keywords arguments
    - kwargs is a dict of keywords arguments (keyword, arg) pairs
    """
    print args, kwargs


fnVariableArgLength() # () {}
fnVariableArgLength(1, 2, 3) # (1, 2, 3) {}
fnVariableArgLength(foo='bar') # () {'foo': 'bar'}
fnVariableArgLength(1, 2, 3, foo='bar') # (1, 2, 3) {'foo': 'bar'}

Modifier Votre cas d'utilisation

def foo(*args,*kw):
    x= kw.get('x',None if len(args) < 1 else args[0])
    y= kw.get('y',None if len(args) < 2 else args[1])
    z= kw.get('z',None if len(args) < 3 else args[2])
    # the rest of foo

foo(1)         # should call foo(1, None, None)
foo(y=2)       # should call foo(None, 2, None)
foo(1,2,3,4,5) # should call foo(1, 2, 3)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top