2015-02-16 27 views
8

Tôi tìm kiếm về nó và nhận được thông tin sau, python obtain variable name of argument in a function nhưng tôi không nhận được câu trả lời bắt buộc và thực sự nhận được lỗi nói add() lấy chính xác 0 đối số khi tôi sử dụng kwargs. Vì vậy, reposted để có được một câu trả lời nếu có bất kỳ.Lấy tên tham số

tôi đã đoạn mã sau,

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

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

tôi muốn đầu ra như

x y 15 
+6

Để có được kết quả chính xác mà bạn yêu cầu chỉ đơn giản là ** không thể **. Vào thời điểm 'add' bắt đầu, những cái tên bạn thèm in chỉ là không có ở đó để lấy ra. Hãy từ bỏ điều này và chấp nhận các lựa chọn thay thế như bạn trích dẫn và hiểu lầm (yêu cầu một cuộc gọi 'thêm (x = x, y = y)' để thực sự ** bảo toàn ** những tên bạn khao khát quá tệ - vì bất kỳ lý do sai lầm nào :-) –

+2

Để thêm vào những gì Alex nói, hơn nữa, nếu hàm được gọi là 'add (3, 4)' hoặc 'add (some_other_func(), a + b)', thì tên tham số là gì? – Thanatos

+0

@AlexMartelli Hãy suy nghĩ về cách trong trường hợp của một lỗi, một traceback có thể cho bạn thấy chính xác mà nguồn dòng lên ngăn xếp kích hoạt lỗi. Vì vậy, không, nó không phải là không thể. – tripleee

Trả lời

7

Bạn nên sử dụng func_code.co_varnames thuộc tính của chức năng của bạn để tên thông số truy cập:

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

add(10, 5) 

Đầu ra:

arg1 arg2 15 

Bạn có thể đọc thêm về các thuộc tính nội bộ ở đây: https://docs.python.org/2/library/inspect.html#types-and-members

+0

Không biết về điều đó.Cool – vks

+0

Chỉ có một vấn đề - thuộc tính đó giữ tất cả các tên biến được xác định bên trong hàm, đó là lý do tại sao tôi đã xóa biến z. –

+0

Hoặc bạn có thể sử dụng func_code.co_varnames [: 2] slice. –

4

Tôi nghĩ gần nhất bạn có thể nhận được những gì bạn muốn thực hiện như sau:

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) 

Kết quả trong:

y x 15 
t w 22 
+0

@vks Tôi không nghĩ rằng kết quả của add.func_code.co_varnames là 'x' và' y' tên. Nó sẽ chỉ cung cấp tên của các đối số hàm, tức là 'arg1',' arg2', không phải 'x' và' y'. – Marcin

+0

Tôi cũng đã thử và nó không làm việc cho tôi. Vì vậy, nếu bạn đặt 'add (x, y)' hàm in 'x y 15' mặc dù các đối số được gọi là' arg1' và 'arg2'? Nếu vậy, bạn có thể cung cấp phiên bản của python mà bạn sử dụng và os. Có lẽ os/python của nó cụ thể. – Marcin

+0

Đúng, anh ta muốn x và y. tên của các đối số đầu vào. Vì vậy, nó đã được giải thích nó không thể được thực hiện. Sử dụng dict là đóng cửa bạn có thể có thể nhận được nó. – Marcin

2

Một giải pháp lót ở đây, **kwargs trả về một dict, hãy kiểm tra với;

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

add(x=5,y=10) 

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

Đó là thông thường. Bạn có thể tiếp cận từng phần tử bằng các phương thức dict cơ bản.

print (kwargs.keys()) 

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

Sử dụng kwargs là một truyền thống thực sự, bạn có thể sử dụng bất kỳ thứ gì bạn muốn thay thế. Đây là giải pháp, in các khóa dict và tổng các giá trị;

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

add(x=5,y=10) 

>>> 
x y 15 
>>> 
1

Bạn có thể làm điều đó bằng mô-đun 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) 

Tuy nhiên, regex cần được cải thiện và sau đó, yêu cầu gọi hàm không được trải rộng trên nhiều dòng.

Tốt hơn để sửa đổi mã của bạn nếu có thể vì điều này lộn xộn.

Các vấn đề liên quan