2015-02-16 15 views
8

Szukałem o tym i otrzymałem następujące, python obtain variable name of argument in a function, ale nie otrzymuję wymaganej odpowiedzi i rzeczywiście otrzymuję komunikat o błędzie: add() przyjmuje dokładnie 0 argumentów, gdy użyłem kwargs. Przeładowane, aby uzyskać odpowiedź, jeśli taka istnieje.Otrzymywanie nazwy parametru

Mam następujący kod,

def add (arg1, arg2): 
    z = arg1 + arg2 
    print arg1Name, arg2Name, z 

x = 10 
y = 5 
add(x,y) 

chcę wyjście jako

x y 15 
+6

Aby uzyskać dokładny wynik, którego potrzebujesz, jest po prostu ** niemożliwy **. Zanim zacznie się 'add', nazwy, których pragniesz wydrukować, nie będą dostępne do pobrania. Porzuć to i zaakceptuj alternatywy, takie jak te, które cytujesz i źle rozumiesz (wymagające wywołania 'add (x = x, y = y)', aby faktycznie ** zachowały ** te nazwy, których tak bardzo pragniesz - z każdego niewłaściwego powodu :-) –

+2

Aby dodać do tego, co mówi Alex, ponadto, jeśli funkcja nazywa się 'add (3, 4)' lub 'add (some_other_func(), a + b)', to jaka jest "nazwa parametru"? – Thanatos

+0

@AlexMartelli Pomyśl o tym, jak w przypadku błędu, traceback może pokazać dokładnie, które linie źródłowe stosu spowodowały błąd. Więc nie, to nie jest niemożliwe. – tripleee

Odpowiedz

7

Należy użyć atrybutu func_code.co_varnames swojej funkcji z parametrami dostępu nazwami:

def add(arg1, arg2): 
    z = arg1 + arg2 
    print ' '.join(add.func_code.co_varnames[:2]) + ' ' + str(z) 

add(10, 5) 

Wyjście:

arg1 arg2 15 

można przeczytać więcej na temat cech wewnętrznych tutaj: https://docs.python.org/2/library/inspect.html#types-and-members

+0

Nie wiedziałem o tym.Cool – vks

+0

Tylko jeden problem - ten atrybut zawiera wszystkie nazwy zmiennych, które zdefiniowano w funkcji, dlatego usunięto zmienną z. –

+0

Lub możesz użyć func_code.co_varnames [: 2] slice. –

4

myślę najbliżej można dostać się do tego, co chcesz, jest w następujący sposób:

def add (**kwargs):  

    assert len(kwargs) == 2, "Not enough arguments"  

    keys = kwargs.keys() 
    z = kwargs[keys[0]] + kwargs[keys[1]] 
    print keys[0], keys[1], z 


x = 10 
y = 5 
add(x=x,y=y) 
add(w=11,t=11) 

Wyniki w:

y x 15 
t w 22 
+0

@vks Nie sądzę, aby add.func_code.co_varnames powodowało wyprowadzanie nazw 'x' i' y'. Poda tylko nazwy argumentów funkcji, tj. "Arg1", "arg2", a nie "x" i "y". – Marcin

+0

Próbowałem również i to nie działa dla mnie. Więc jeśli wstawisz 'add (x, y)' funkcja wypisze 'x y 15', mimo że argumenty są nazywane' arg1' i 'arg2'? Jeśli tak, czy możesz podać wersję pythona, której używasz i os. Być może jego specyficzny dla os/python. – Marcin

+0

Tak, chce x i y. nazwa argumentów wejściowych. Tak więc zostało już wyjaśnione, że nie można tego zrobić. Używanie Dicta to zamknięcie, do którego prawdopodobnie możesz się dostać. – Marcin

2

Jedno rozwiązanie z tuleją, **kwargs zwraca komunikat, sprawdź to za pomocą;

def add(**kwargs): 
    print (kwargs) 

add(x=5,y=10) 

>>> 
{'y': 10, 'x': 5} 
>>> 

To normalny dykt. Możesz dotrzeć do każdego elementu za pomocą podstawowych metod dyktowania.

print (kwargs.keys()) 

>>> 
dict_keys(['y', 'x']) 
>>> 

Korzystanie kwargs tradycja rzeczywiście, można użyć co chcesz zamiast niego. Oto rozwiązanie, wydrukuj klucze dyktujące i sumę wartości;

def add(**ChuckNorris): #instead of **kwargs 
    print (" ".join(ChuckNorris.keys()),sum(list(ChuckNorris.values()))) 

add(x=5,y=10) 

>>> 
x y 15 
>>> 
1

Można to zrobić za pomocą modułu traceback.

def get_current_arg_names(): 
    import traceback, re 
    tb = traceback.extract_stack() 
    method = tb[-2][2] 
    func_call = tb[-3][3] 
    args = re.search('%s\s*\((.*?)\)' % method, func_call).group(1) 
    return [ x.strip() for x in args.split(',') ] 

def add(arg1, arg2): 
    z = arg1 + arg2 
    print get_current_arg_names(), z 
    return z 

x = 1 
y = 3 
print add(x, y) 

Jednak regex musiałby zostać poprawione i wydarzenie wtedy, istnieje wymóg, że nie wywołanie funkcji być rozłożone na wielu liniach.

Lepiej zmodyfikować kod, jeśli to możliwe, ponieważ jest brudny.

Powiązane problemy