¿Hay una manera de invocar una función de Python con el número incorrecto de argumentos sin invocar un TypeError?

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

  •  06-09-2019
  •  | 
  •  

Pregunta

Cuando se llama a una función con un número incorrecto de argumentos, o con un argumento de palabra clave que no está en su definición, se obtiene una TypeError. Me gustaría tener una pieza de código para tomar una devolución de llamada e invocar con argumentos variables, basadas en lo que es compatible con la devolución de llamada. Una forma de hacerlo sería que, para un cb de devolución de llamada, utilizar cb.__code__.cb_argcount y cb.__code__.co_varnames, pero preferiría abstracto que en algo así como apply, pero que sólo se aplica a los argumentos que "encajan".

Por ejemplo:

 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.

¿Hay algo como esto ya en Python, o es algo que debería escribir desde cero?

¿Fue útil?

Solución

En lugar de cavar en los detalles usted mismo, puede inspeccionar la firma de la función - es probable que desee inspect.getargspec(cb)

.

Exactamente cómo desea utilizar esa información y los argumentos que tiene, al llamar a la función "correctamente", no es del todo claro para mí. Suponiendo por simplicidad que sólo se preocupan por simples argumentos nombrados, y los valores que le gustaría pasar están en d dict ...

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

Tal vez usted quiere algo más elaborado, y puede elaborar sobre exactamente qué?

Otros consejos

Esto tal vez?

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'}

Editar Sus casos de uso

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top