a

Câu hỏi Chấp nhận một từ điển làm đối số với argparse và python [duplicate]


Câu hỏi này đã có câu trả lời ở đây:

Tôi đang cố gắng chấp nhận một đối số của type = dict với argparse nhưng không có vấn đề đầu vào nó cho một lỗi của giá trị dict không hợp lệ.

#!/usr/bin/env python

import argparse

MYDICT = {'key': 'value'}

parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mydict", action="store",
                    required=False, type=dict,
                    default=MYDICT)

args = parser.parse_args()

print args.mydict

Đây là những gì xảy ra khi tôi thử và chuyển một từ điển sang kịch bản

./argp.py -m "{'key1': 'value1'}"
usage: argp.py [-h] [-m MYDICT]
argp.py: error: argument -m/--mydict: invalid dict value: "{'key1': 'value1'}"

Nhìn vào các tài liệu tôi nghĩ rằng điều này là có thể.

http://docs.python.org/dev/library/argparse.html

“Bất kỳ đối tượng nào hỗ trợ toán tử in đều có thể được chuyển thành giá trị lựa chọn, vì vậy các đối tượng dict, các đối tượng thiết lập, các thùng chứa tùy chỉnh, vv đều được hỗ trợ.”


24
2017-09-04 08:22


gốc


Dòng bạn trích dẫn từ tài liệu liên quan đến đối số từ khóa "lựa chọn", xác định giá trị của các đối số được cho phép. Thông qua một dict để lựa chọn có hiệu quả tương đương với đi qua một danh sách các phím. Do đó, việc chuyển "{'a': 2, 'b': 3}" sẽ hạn chế các đối số được phép cho cờ "--mydict" thành "a" hoặc "b". - Pascal Bugnion


Các câu trả lời:


Tôi không nghĩ rằng nó có thể vượt qua một từ điển như là một đối số trong dòng lệnh bởi vì không tồn tại một chức năng chuyển đổi từ chuỗi để dict (CHỈNH SỬA: Một hack  có thể, xem bên dưới). Những gì bạn về cơ bản nói python để làm là:

dict("{'key1': 'value1'}")

Mà nếu bạn thử nó trong giao diện điều khiển python, không hoạt động.

Cụm từ:

"Bất kỳ đối tượng nào hỗ trợ toán tử in đều có thể được chuyển thành giá trị lựa chọn, vì vậy đối tượng dict, đối tượng đã đặt, vùng chứa tùy chỉnh, v.v ... đều được hỗ trợ".

đề cập đến là lựa chọn đối số có thể được chuyển với add_argument chức năng - không cho kiểu tranh luận.

Đặt cược tốt nhất của bạn là có thể chấp nhận đối số của bạn dưới dạng một chuỗi và sau đó chuyển đổi nó bằng cách sử dụng json khả năng của python:

parser.add_argument('-m', '--my-dict', type=str)
args = parser.parse_args()

import json
my_dictionary = json.loads(args.my_dict)

Sau đó, bạn có thể chuyển một từ điển dưới dạng một chuỗi. Bạn có thể thử bộ mã hóa / giải mã json cho chính mình trong giao diện điều khiển python để xem nó hoạt động như thế nào:

>>>json.loads('{"value1":"key1"}')
{u'value1': u'key1'}

CHỈNH SỬA: hpaulj đã chỉ ra với tôi rằng bạn có thể "hack" kiểu tham số bằng cách truyền json.loads.

import json
parser.add_argument('-d', '--my-dict', type=json.loads)
args = parse.parse_args()

mydict = args.my_dict  # Will return a dictionary

Lý do công trình này thực sự khá thú vị bởi vì argparse nội bộ sẽ chỉ sử dụng giá trị tham số như một hàm để chuyển đổi đối số. tức là nếu type = int thì nó sẽ sử dụng int (arg) hoặc nếu type = json.loads sau đó json.loads (arg)

Điều này cũng có nghĩa là bạn có thể chuyển bất kỳ hàm nào có tham số đơn lẻ làm đối số để nhập và thực hiện chuyển đổi tùy chỉnh nếu bạn cần :)


32
2017-09-04 08:52



type=json.loads công trinh - hpaulj
Điều đó thực sự có ý nghĩa rất nhiều vì như tôi đã đề cập ở trên, tham số được truyền cho kiểu được xử lý bằng cách đặt đối số trong dấu ngoặc đơn. Cảm ơn bạn đã chỉ ra điều đó. - Michael Aquilina
Tôi sẽ không nhất thiết phải gọi đó là "hack". Nó thực sự là cách đối số kiểu được cho là hoạt động - mdw7326
liệu nó có quản lý giá trị mặc định cho mỗi giá trị khóa không? - Prasath