2010-01-18 63 views
17

Tôi đang sử dụng getopt để xử lý đối số tùy chọn dòng lệnh, nên chấp nhận danh sách. Một cái gì đó như thế này:chỉ định danh sách dưới dạng đối số dòng lệnh trong python

foo.py --my_list=[1, 2, 3, 4,5] 

Nhưng điều này Trims tất cả mọi thứ sau "[1,"

Câu hỏi của tôi là: A) Có cách nào để xác định một danh sách mà không chuyển đổi nó thành một chuỗi? (sử dụng getopt)

B) Nếu tôi chuyển đổi danh sách thành chuỗi, cách chuyển đổi danh sách này thành chuỗi? ví dụ. một cái gì đó như mylist.split ("?") để thoát khỏi dấu ngoặc vuông ?? Có cách nào tốt hơn?

Cảm ơn bạn

Trả lời

23

Có hai lựa chọn mà tôi có thể nghĩ đến:

  • Sử dụng optparse, và sử dụng append hành động để xác định những gì bạn muốn làm như: foo.py --my_list=1 --my_list=2 ....
  • Chỉ định dòng lệnh của bạn dưới dạng foo.py --my_list='1,2,3,4,5' và sau đó sử dụng x.split(',') để nhận giá trị của bạn trong danh sách. Bạn có thể sử dụng getopt hoặc optparse cho phương pháp này.

Lợi thế của phương pháp đầu tiên là bạn có thể nhận giá trị số nguyên trong danh sách trực tiếp, chi phí của lệnh dài hơn (nhưng bạn có thể thêm tùy chọn đơn charecter cho --my_list nếu muốn). Ưu điểm của dòng thứ hai là dòng lệnh ngắn hơn, nhưng sau split(), bạn cần chuyển đổi các giá trị chuỗi '1', '2', v.v. thành các số nguyên (khá dễ dàng).

+2

vì bài đăng này là 5 tuổi, 'optparse' hiện không còn được dùng cho' argparse' – SAAD

+0

Bạn có ý nghĩa gì khi 'sử dụng hành động chắp thêm'? Nghe có vẻ thú vị nhưng không chắc bạn đang nói gì. –

+0

@MonicaHeddneck Xem https://docs.python.org/3/library/optparse.html#standard-option-actions - chúng có ví dụ về hành động "chắp thêm": 'parser.add_option (" - t "," --tracks ", action =" append ", type =" int ")'. –

7

Có thể bạn chỉ cần đặt đối số trong dấu ngoặc kép?

foo.py "--my_list=[1, 2, 3, 4,5]" 

Nếu không, mọi không gian sẽ được coi là dấu tách cho đối số.

+2

Và đó là không phải vì python nhưng do vỏ mà phân tích các đối số và cung cấp cho họ với chương trình python. – extraneon

+1

Đúng một phần. Trên Windows dòng lệnh chỉ là một chuỗi. Và thậm chí UNIX không có bất kỳ cấu trúc dữ liệu đặc biệt nào mà chuyển các đối số cho chương trình, nó vẫn chỉ là một chuỗi. Tuy nhiên, đó là một quy ước được triển khai rộng rãi, nhưng không phổ biến. Và có, thời gian chạy C có thông số kỹ thuật cho điều đó. – Joey

+1

Bạn cũng có thể thực hiện '--my-list =" [1, 2, 3, 4,5] "'. Tôi thường sử dụng biểu mẫu này vì nó thường giống như '--my-list =" $ MY_LIST "'. –

1

Từ trang python optparse giúp đỡ: "

parser.add_option("-f") 
parser.add_option("-p", type="float", nargs=3, dest="point") 

Vì nó phân tích các dòng lệnh

-f foo.txt -p 1 -3.5 4 -fbar.txt 

optparse sẽ thiết lập

options.f = "foo.txt" 
options.point = (1.0, -3.5, 4.0) 
options.f = "bar.txt" 

"

10

Nếu tôi không thể sử dụng một cú pháp chuẩn (optparse hoặc argparse) để ứng dụng của tôi sau đó tôi sử dụng chức năng ast.literal_eval để phân tích đối số đầu vào của danh sách loại như sau:

import sys, ast 

inputList = ast.literal_eval(sys.argv[1]) 
print type(inputList) 
print inputList 

Để cho giả sử rằng mã này được lưu trữ trong tệp testParser.py.Bằng cách thực hiện các kịch bản:

$ python testParser.py "[1,2,3,4, [123, 456, 789], 'asdasd']" 

chúng tôi nhận được kết quả như sau:

<type 'list'> 
[1, 2, 3, 4, [123, 456, 789], 'asdasd'] 

Vì vậy, sử dụng chức năng đủ ast.literal_eval an toàn và chèn danh sách như là một chuỗi mã chúng ta có kết quả mong muốn.

Liên kết hữu ích:

Using python's eval() vs. ast.literal_eval()?

http://docs.python.org/2/library/functions.html?highlight=eval#eval

1

Một cách cập nhật là để sử dụng thư viện argparse và thêm danh sách như một đối số dòng lệnh. Bằng cách này, bạn không phải làm bất kỳ phân tích thủ công nào.

Ví dụ:

parser = argparse.ArgumentParser() 
parser.add_argument(
     "-values", 
     nargs="*", # expects ≥ 0 arguments 
     type=int, 
     default=[35, 40, 50, 60, 70, 80, 90], # default list if no arg value 
    ) 

nào thì bạn sẽ gọi như thế này:

python3 someprogram.py -values 1 2 3 
Các vấn đề liên quan