2012-01-27 46 views
26

Tôi chỉ mới bắt đầu với python vì vậy tôi đang đấu tranh với một ví dụ khá đơn giản. Về cơ bản tôi muốn vượt qua tên của một thực thi cộng với đầu vào của nó qua các đối số dòng lệnh, ví dụ .:Tham số dòng lệnh Python

python myprogram refprogram.exe refinput.txt 

Điều đó có nghĩa khi thực hiện myprogram, nó thực thi refprogram.exe và vượt qua nó như là đối số refinput. Tôi cố gắng để làm điều đó theo cách sau:

import sys, string, os 
print sys.argv 

res = os.system(sys.argv(1)) sys.argv(2) 
print res 

Các thông báo lỗi mà tôi nhận được là:

res = os.system(sys.argv(1)) sys.argv(2) 
         ^
SyntaxError: invalid syntax 

Bất cứ một ý tưởng những gì tôi đang làm sai?

Tôi đang chạy Python 2.7

+3

Tôi muốn máy tính của tôi sẽ cho tôi một massage lỗi. :-) – LarsH

Trả lời

61

này dòng

res = os.system(sys.argv(1)) sys.argv(2) 

là sai trong một vài cách khác nhau.

Đầu tiên, sys.argv là một danh sách, vì vậy bạn sử dụng dấu ngoặc vuông để truy cập nội dung của nó:

sys.argv[1] 
sys.argv[2] 

Thứ hai, bạn đóng ngoặc đơn của bạn trên os.system quá sớm, và sys.argv(2) còn lại treo tắt của phần cuối của nó. Bạn muốn di chuyển dấu đóng ngoặc đơn ở cuối dòng, sau tất cả các đối số.

Thứ ba, bạn cần phân tách các đối số bằng dấu phẩy, một không gian đơn giản sẽ không thực hiện.

dòng cuối cùng của bạn sẽ trông như thế này:

res = os.system(sys.argv[1], sys.argv[2]) 
8

sys.argv là một danh sách, và được lập chỉ mục sử dụng dấu ngoặc vuông, ví dụ sys.argv[1]. Bạn có thể muốn kiểm tra len(sys.argv) trước khi lập chỉ mục nó.

Ngoài ra, nếu bạn muốn chuyển các tham số đến os.system(), bạn có thể muốn một cái gì đó như os.system(' '.join(sys.argv[1:])), nhưng điều này sẽ không hoạt động đối với các không gian. Bạn nên sử dụng mô-đun subprocess.

3

sys.argv là danh sách

import sys, string, os 
print sys.argv 

res = os.system(sys.argv[1]) sys.argv[2] 
print res 
1

Nếu bạn đang chạy Python 2.7 nó được khuyến khích sử dụng các mô-đun mới subprocess.

Trong trường hợp này bạn sẽ viết

import sys, subprocess 
result = subprocess.check_output(sys.argv[1], sys.argv[2]) 
29

Một đến nay, cách tốt hơn để làm điều này là với argparse library. Thư viện envoy wrapper làm cho subprocess dễ dàng hơn để làm việc với.

Một ví dụ đơn giản:

import argparse 
import envoy 

def main(**kwargs): 
    for key, value in kwargs.iteritems(): 
     print key, value 
    cmd = '{0} {1}'.format(kwargs['program'], ' '.join(kwargs['infiles'])) 
    r = envoy.run(cmd) 
    print r.std_out 
    print r.std_err 

if __name__ == '__main__': 
    parser = argparse.ArgumentParser(description='Get a program and run it with input', version='%(prog)s 1.0') 
    parser.add_argument('program', type=str, help='Program name') 
    parser.add_argument('infiles', nargs='+', type=str, help='Input text files') 
    parser.add_argument('--out', type=str, default='temp.txt', help='name of output file') 
    args = parser.parse_args() 
    main(**vars(args)) 

này đọc trong các đối số, phân tích chúng, sau đó gửi chúng tới các phương pháp chính như một cuốn từ điển các từ khóa và giá trị. Điều đó cho phép bạn kiểm tra phương thức chính của mình một cách độc lập khỏi mã đối số của bạn, bằng cách chuyển vào một từ điển được xây dựng sẵn.

Phương thức chính sẽ in các từ khóa và giá trị. Sau đó, nó tạo ra một chuỗi lệnh, và chuyển cho phái viên để chạy. Cuối cùng, nó in đầu ra từ lệnh.

Nếu bạn đã cài đặt pip, sứ giả có thể được cài đặt với pip install envoy. Cách dễ nhất để lấy pip là với pip-installer.

+2

Đồng ý chung (argparse là tuyệt vời), mặc dù cho một kịch bản utlity của người mới bắt đầu, nó có thể là quá mức cần thiết. – delnan

+3

@delnan Nó giải quyết rất nhiều vấn đề, rằng tôi nghĩ tốt hơn là chỉ cắn viên đạn và học nó. Tôi cũng đã thêm một chút về cách sử dụng 'envoy' thay vì 'os.command' vì tôi đã bỏ lỡ điều đó trong câu hỏi ban đầu. –

+4

Nó không bao giờ quá mức cần thiết. Các kịch bản lệnh tiện ích có cách trở thành các tính năng sản xuất lâu dài. –

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