2013-11-28 28 views
6

Tôi có thể chuyển đổi chuỗi thành danh sách đối số trong python không?python chuyển đổi chuỗi thành danh sách đối số

def func(**args): 
    for a in args: 
     print a, args[a] 

func(a=2, b=3) 

# I want the following work like above code 
s='a=2, b=3' 
func(s) 

tôi biết:

danh sách có thể, chỉ cần sử dụng * danh sách, nhưng danh sách không thể có một yếu tố như: a = 2

và eval chỉ có thể đánh giá biểu hiện

mà sẽ như thế nào:

def func2(*args): 
    for a in args: 
     print a 

list1=[1,2,3] 
func2(*list1) 
func2(*eval('1,2,3')) 
+0

Giống như [argparse] (http://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser.parse_args) nên làm điều đó. hãy xem cách gọi 'parse_args()' với các đối số. –

Trả lời

8

Bạn có thể xoa bóp chuỗi đầu vào vào từ điển và sau đó gọi hàm của bạn bằng từ đó, ví dụ:

>>> x='a=2, b=3' 
>>> args = dict(e.split('=') for e in x.split(', ')) 
>>> f(**args) 
a 2 
b 3 
+0

Đầu tiên nhìn thấy cú pháp này. Cảm ơn bạn. Tôi không biết tại sao 'tuple (e.split ('=')) cho e trong x.split (',')' sẽ gây ra lỗi cú pháp, không phải là một đối số của dict()? Có giải thích về quy tắc này không? –

+0

@AylwynLake: Nó là một [biểu thức máy phát điện] (http://www.python.org/dev/peps/pep-0289/) mà lần lượt là một dạng tổng quát của [list comprehensions] (http: // docs. python.org/2/tutorial/datastructures.html#list-comprehensions). –

7

Bạn muốn có một từ điển , không phải là 'danh sách đối số'. Bạn cũng sẽ được tốt hơn bằng cách sử dụng ast.literal_eval() để đánh giá chỉ Python literals:

from ast import literal_eval 

params = "{'a': 2, 'b': 3}" 
func(**literal_eval(params)) 

Trước khi bạn đi tuyến đường này, chắc chắn rằng bạn đã khám phá các lựa chọn khác cho các tùy chọn marshalling đầu tiên, chẳng hạn như argparse cho các tùy chọn dòng lệnh , hoặc JSON cho chuyển giao dựa trên mạng hoặc dựa trên tệp hoặc sự kiên trì.

+1

+1 nhưng giải pháp này có thể không áp dụng được trong trường hợp chuỗi 'a = 2, b = 3' là đầu vào của người dùng (ví dụ: từ tệp cấu hình hoặc tương tự); bạn không muốn cho phép đánh giá mã Python tùy ý. : -} –

+0

@ FrerichRaabe: OP dường như đang tìm kiếm tương đương với 'args '(1, 2, 3)" 'và' func2 (* literal_eval (args)) 'ở đây; ví dụ. cái gì đó sẽ tạo ra cấu trúc python đúng để áp dụng cho cuộc gọi. –

+0

@MartijnPieters: Ý tôi là Frerich Raabe nói. Tôi muốn đọc từ tập tin cấu hình của bảng, sau đó sử dụng sqlalchemy để tự động tạo ra các bảng. khi xử lý Column ('id', Integer, primary_key = True). Sau đó đặt câu hỏi này. –

0

Bạn có thể sử dụng chuỗi làm danh sách đối số trực tiếp trong cuộc gọi đến eval, ví dụ:

def func(**args): 
for a in args: 
    print(a, args[a]) 

s='a=2, b=3' 

eval('func(' + s + ')') 
>>>b 3 
>>>a 2 

lưu ý rằng func cần nằm trong không gian tên để gọi eval hoạt động như thế này.

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