2012-06-02 14 views
36

Zastanawiam się, czy istnieje sposób określić (biorąc pod uwagę zmienną zawierającą lambda) liczbę parametrów, jakie zawiera lambda. Powodem jest, że chcę wywołać funkcję warunkowo zależną od liczby parametrów.Określanie liczby parametrów w lambda

Co szukam

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

Więc mogę zrobić coś takiego

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) 

Odpowiedz

38

Jestem omijając część o jak liczyć argumenty, bo nie wiem jak chcesz wziąć pod uwagę varargs i słowa kluczowe. Ale to powinno zacząć.

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

Brzmi jak inspect.getargspec is deprecated jak Pythona 3 (dzięki @JeffHeaton). Zalecane rozwiązanie to inspect.signature. Ten element wyniku zawiera różne struktury w zależności od ułożenia parametrów dla danej funkcji, ale pasuję do mojej funkcji z powyższego przykładu 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

wygląda inspect.getargspec jest przestarzała, jest zalecane, aby użyć inspect.signature – JeffHeaton

50

Lambda działa jak każdy inny. Liczba argumentów jest przechowywana w 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 Świetna odpowiedź - chciałbym móc przyjąć dwie odpowiedzi. Tak właśnie sprawdza się inspect.py (sprawdził źródło). –

+7

Ale używając 'inspect' uzyskasz funkcję" przenośną ", widząc jak zmieniła się nazwa atrybutu z Python 2 na Python 3. –

10

Z dokumentacji na callable types atrybut funkcji func_code zawiera obiekt kodu, a od dokumentacji modułu wglądu na code objects jest członkiem co_argcount który zawiera liczbę argumentów (nie wliczając * lub ** args) .

Więc najlepszym sposobem, aby uzyskać tę informację z funkcji lambda (lub dowolnej funkcji) jest użycie func.func_code.co_argcount:

>>> foo = lambda a, b, *args, **kwargs: None 
>>> foo.func_code.co_argcount 
2 
Powiązane problemy