Câu trả lời và nhận xét đã xóa cho biết có một số nhầm lẫn về những gì bạn muốn. Vì vậy, tôi sẽ thêm vào sự nhầm lẫn đó.
Thông thường trình phân tích cú pháp không ghi chuỗi tùy chọn. Tuy nhiên, nó được cung cấp cho phương thức Action
__call__
. Vì vậy, một lớp Action có thể lưu nó. Ví dụ về lớp tùy chỉnh FooAction
trong tài liệu argparse minh họa điều này.
Nếu tôi xác định lớp con hành động này:
In [324]: class PassThru(argparse._StoreAction):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, [values, option_string])
In [324]: p.add_argument('-o','--other',action=PassThru)
Chuỗi tùy chọn được ghi lại cùng với các giá trị ('-o' hoặc '--Góc'):
In [322]: p.parse_args('-p test -o teseting'.split())
Out[322]: Namespace(other=['teseting', '-o'], pass_me_on='test')
In [323]: p.parse_args('-p test --other teseting'.split())
Out[323]: Namespace(other=['teseting', '--other'], pass_me_on='test')
Rõ ràng là option_string và giá trị có thể được ghi theo thứ tự khác, trong từ điển, dưới dạng thuộc tính riêng biệt trong Không gian tên, v.v.
Có nhiều cách khác để chuyển các tùy chọn cho một chương trình khác, đặc biệt nếu trình phân tích cú pháp gói không cần xử lý chúng.
argparse
lấy đối số từ sys.argv[1:]
và không thay đổi đối số. Vì vậy, ngay cả khi trình phân tích cú pháp của bạn sử dụng một số đối số, bạn có thể chuyển danh sách đó vào popen
(tất cả hoặc một phần).
Tài liệu argparse có một ví dụ, dưới nargs=REMAINDER
, về phân tích cú pháp một số đối số cho chính nó và thu thập phần còn lại để chuyển sang chương trình khác.Đây là ví dụ của họ:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
Vì vậy, bạn có thể gọi popen
với một cái gì đó giống như
plist = ['wrapped_program']
plist.extend(args.args)
popen(plist, ...)
Sử dụng parse.parse_known_args
cũng có thể được sử dụng để thu thập lời chưa phân tích thành một danh sách 'extras'. Phần đó của các tài liệu nói về việc truyền các chuỗi đó đến một chương trình khác (giống như bạn đang làm). Ngược lại với trường hợp REMAINDER, các công cụ bổ sung không nhất thiết phải là cuối cùng.
Những công việc này, tất nhiên, chỉ khi trình phân tích cú pháp này không cần --pattern
cho chính nó. Nếu nó phân tích cú pháp, nó sẽ không xuất hiện trong REMAINDER hoặc phần bổ sung. Trong trường hợp đó bạn sẽ phải thêm nó trở lại danh sách mà bạn cung cấp popen
tôi sẽ tinh chỉnh phân tích cú pháp của bạn như sau:
pass_1 = 'passed' # without the -- or internal -
dpass_` = '--'+pass_
parser = argparse.ArgumentParser()
parser.add_argument("-p", dpass_1, help="Pass me on")
parser.add_argument("-k", "--arg-for-wrapper")
args = parser.parse_args()
process = Popen(['wrapped_program', dpass_1, getattr(args, pass_1)], ...)
tùy chọn khác:
parser = argparse.ArgumentParser()
pass_action = parser.add_argument("-p", '--pass-me-on', help="Pass me on")
parser.add_argument("-k", "--arg-for-wrapper")
args = parser.parse_args()
Nếu bạn in pass_action
(trong một vỏ) bạn sẽ nhận được một cái gì đó như:
_StoreAction(option_strings=['-p', '--pass-me-on'], dest='pass_me_on', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
Vì vậy, bạn c Ould kéo --name
và dest
từ đối tượng đó, như sau:
process = Popen(['wrapped_program', pass_action.option_strings[-1], getattr(args, pass_action.dest), ...], ...)
Bạn cần phải nhìn vào sys.argv
để xem option_string đã được sử dụng (dài, ngắn hoặc khác). Trình phân tích cú pháp không ghi lại bất cứ đâu.
Lưu ý '--pass-me-on' được sản xuất dest='pass_me_on'
. Việc chuyển đổi -
thành _
có thể làm phức tạp phát sinh một chuỗi từ chuỗi kia.
Nếu bạn có chuỗi dest
, bạn phải sử dụng getattr
để kéo nó từ không gian tên args hoặc sử dụng vars(args)[dest]
(truy cập từ điển).
Một vấn đề khác. Nếu --patten
có nargs='+', its value will be a list, as opposed to a string. You'd have to careful when merging that into the
danh sách đối số popen`.
Tại sao bạn không chỉ cần lưu nó trong một biến? '' pattern_str = '--pattern''', rồi '' ..add_argument (... pattern_str ...) ''. Ở đó - chỉ có một điểm duy trì. –
Có vẻ như bạn đang cố gắng mã hóa một sự phụ thuộc giữa hai chương trình riêng biệt (và không linh hoạt như vậy: "các chương trình này phải chia sẻ tên tùy chọn"). Đó có thực sự là điều bạn muốn làm không? – Hurkyl
@Hurkyl Có, chương trình python là một trình bao bọc cho một chương trình khác. – user80551