2012-06-02 26 views
36

Me pregunto si hay una manera de determinar (dada una variable que contiene una lambda) el número de parámetros que contiene la lambda. La razón es que deseo llamar a una función condicionalmente dependiente del número de parámetros.Determinar el número de parámetros en una lambda

Lo que estoy buscando

def magic_lambda_parameter_counting_function(lambda_function): 
    """Returns the number of parameters in lambda_function 

    Args: 
     lambda_function - A lambda of unknown number of parameters 
    """ 

Así que puedo hacer algo como

def my_method(lambda_function): 

    # ... 
    # (say I have variables i and element) 

    parameter_count = magic_lambda_parameter_counting_function(lambda_function) 

    if parameter_count == 1: 
     lambda_function(i) 
    elif parameter_count == 2: 
     lambda_function(i, element) 

Respuesta

38

me estoy saltando la parte sobre cómo contar los argumentos, porque no sé cómo desea considerar varargs y palabras clave. Pero esto debería hacerte comenzar.

>>> import inspect 
>>> foo = lambda x, y, z: x + y + z 
>>> inspect.getargspec(foo) 
ArgSpec(args=['x', 'y', 'z'], varargs=None, keywords=None, defaults=None) 

que suena como inspect.getargspec is deprecated de Python 3 (gracias a @JeffHeaton). La solución recomendada usa inspect.signature. El miembro .parameters del resultado contiene una variedad de estructuras que dependen de la disposición de los parámetros para la función en cuestión, pero estoy haciendo coincidir mi función con el ejemplo anterior de Python 2.

>>> import inspect 
>>> foo = lambda x, y, z: x + y + z 
>>> inspect.signature(foo).parameters 
mappingproxy(OrderedDict([('x', <Parameter "x">), ('y', <Parameter "y">), ('z', <Parameter "z">)])) 
+1

parece inspect.getargspec es obsoleto, se sugiere utilizar inspect.signature – JeffHeaton

50

Lambdas son funciones como cualquier otra. El número de argumentos se almacena en func.__code__.co_argcount.

>>> foo = lambda x, y=2: x+y 
>>> foo.__code__.co_argcount 
2 
>>> foo = lambda x, y=2, z=3: x+y+z 
>>> foo.__code__.co_argcount 
3 
+3

+ 1 Gran respuesta: desearía poder aceptar dos respuestas. De hecho, así es como lo hace inspect.py (buscó la fuente). –

+7

Pero usando 'inspeccionar' obtienes la funcionalidad" portátil ", viendo cómo el nombre del atributo cambió de Python 2 a Python 3. –

10

De la documentación en callable types, el atributo func_code de funciones contiene un objeto de código, y de la documentación del módulo de inspeccionar en code objects hay un miembro co_argcount que contiene el número de argumentos (no incluyendo * o ** args) .

Así que la mejor manera de obtener esta información de una función lambda (o cualquier función) es utilizar func.func_code.co_argcount:

>>> foo = lambda a, b, *args, **kwargs: None 
>>> foo.func_code.co_argcount 
2 
Cuestiones relacionadas