Câu trả lời:
Cuối cùng, sự khác biệt giữa try, exceptvà thử nghiệm len(sys.argv)không phải là tất cả những gì đáng kể. Cả hai đều là một chút hackish so với argparse.
Tuy nhiên, điều này xảy ra với tôi - như một loại lập luận ngân sách thấp:
arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))
Bạn thậm chí có thể sử dụng nó để tạo ra một namedtuplevới các giá trị mặc định None- tất cả trong bốn dòng!
Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))
Trong trường hợp bạn không quen thuộc namedtuple, nó chỉ là một tuple hoạt động giống như một đối tượng, cho phép bạn truy cập các giá trị của nó bằng cách sử dụng tup.attributecú pháp thay vì tup[0]cú pháp.
Vì vậy, dòng đầu tiên tạo một namedtuplekiểu mới với các giá trị cho mỗi giá trị trong arg_names. Dòng thứ hai chuyển các giá trị từ từ argsđiển, sử dụng getđể trả về giá trị mặc định khi tên đối số đã cho không có giá trị liên quan trong từ điển.
Kiểm tra độ dài của sys.argv:
if len(sys.argv) > 1:
blah = sys.argv[1]
else:
blah = 'blah'
Một số người thích cách tiếp cận dựa trên ngoại lệ mà bạn đã đề xuất (ví dụ try: blah = sys.argv[1]; except IndexError: blah = 'blah':), nhưng tôi không thích nó nhiều vì nó không "chia tỷ lệ" gần như độc đáo (ví dụ: khi bạn muốn chấp nhận hai hoặc ba đối số) và nó có thể ẩn các lỗi (ví dụ: nếu bạn đã sử dụng blah = foo(sys.argv[1]), nhưng foo(...)đã nêu ra IndexError, điều đó IndexErrorsẽ bị bỏ qua).
try, except. Chỉ cần đợi foođối số của bạn cho đến elsemệnh đề.
argparse.
argparse.pygia tất cả các dự án dòng lệnh của mình.
trymệnh đề… Vì vậy, cho rằng nó không khó hơn (và, IMO, đẹp hơn một chút), tôi thích chỉ kiểm tra độ dài (ngoài ra, bạn tránh có những người la mắng bạn vì đã sử dụng các ngoại lệ để kiểm soát luồng).
try, tôi phải thừa nhận. Tôi chỉ cảm thấy rằng nó đôi khi thể hiện ý định của tôi rõ ràng hơn là một iftuyên bố.
Một cách khác mà tôi chưa thấy được liệt kê là đặt giá trị sentinel của bạn trước thời hạn. Phương pháp này tận dụng lợi thế của đánh giá lười biếng của Python, trong đó bạn không phải lúc nào cũng phải cung cấp một elsecâu lệnh. Thí dụ:
startingpoint = 'blah'
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
Hoặc nếu bạn đang sử dụng cú pháp CRAZY, bạn có thể sử dụng toán tử bậc ba của Python :
startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'
Tôi sử dụng cái này - nó không bao giờ lỗi:
startingpoint = 'blah'
if sys.argv[1:]:
startingpoint = sys.argv[1]
startingpointbiến khỏi ví dụ, nhưng câu hỏi đang chỉ định một biến dự phòng, vì vậy tôi chỉ thực hiện như vậy.
sys.argv[1:]:. Điều này hoạt động với các đối số vị trí trong khi số đếm thì không.
Đó là một danh sách Python bình thường. Ngoại lệ mà bạn sẽ bắt gặp cho điều này là IndexError, nhưng thay vào đó bạn nên kiểm tra độ dài.
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
else:
startingpoint = 'blah'
Một giải pháp làm việc với fonction tích hợp bản đồ!
arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}
Sau đó, bạn chỉ cần gọi các tham số của mình như sau:
if args['operation'] == "division":
if not args['parameter']:
...
if args['parameter'] == "euclidian":
...
Bạn có thể chỉ cần nối giá trị của argv [1] vào argv và sau đó kiểm tra xem argv [1] không bằng chuỗi bạn đã nhập vào Ví dụ:
from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
print(argv[1])