如何从外部文件指定 argparse 选项?
How to specify argparse options from an external file?
我正在使用 argparse 指定一些参数如下:
my_parser = argparse.ArgumentParser()
my_parser.add_argument("--script_path", nargs='?', type=str, const='', default='', help="Path of the script to pull.")
my_parser.add_argument("--script", nargs='?', type=str, const='', default='', help="Name of the script to get pulled, without script extension.")
my_parser.add_argument("--project", nargs='?', type=str, const='', default='', help="Project.")
my_args = my_parser.parse_args()
my_script_path = my_args.script_path
my_script = my_args.script
my_project = my_args.project
现在我尝试做同样的事情,但不是通过我将加载的 .json 文件定义上述参数。我选择了 .json 因为它看起来不错,欢迎提出更好的建议。
我试过的是有一个像这样的 .json 文件:
[
{
"name_or_flags": ["-sp", "--script_path"],
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run."
},
...
]
加载文件后,我尝试了以下操作但失败了:
my_parser.add_argument(<combination of all keys, values from .json as a dictionary>)
my_parser.add_argument(<*unnamed_tup, **named_dict>)
#unnamed tuple since name_or_flags isn't supposed to be used
#unnamed tuple is only made from name_or_flags
无论我做什么都不行。
有没有人做过类似的事情?
我不想通过外部文件添加值,例如:
只是为了定义参数。
谢谢!
您需要pop("name_or_flags")
,注意始终提供列表;此外,您需要排除 type
,因为它会引发错误(是字符串而不是 class 或函数)。
import argparse
import json
args = json.loads("""
[{
"name_or_flags": "-sp", "--script_path"],
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run."
}]
""")
parser = argparse.ArgumentParser()
for arg in args:
arg.pop("type", None) # will raise ValueError: 'str' is not callable
parser.add_argument(*arg.pop("name_or_flags"), **arg)
# If the type is important to keep, you can always create a dictionary to map a string to a value, that is a builtin class.
mapping = dict(str=str, bool=bool, int=int) # this will map strings to classes
for arg in args:
thetype_str = arg.pop("type", "str")
arg["type"] = mapping.get(thetype_str, str) # if missing or wrong, will give plain string
parser.add_argument(*arg.pop("name_or_flags"), **arg)
这是从文件执行此操作的方法:
import argparse
jdata = [
{
"args": ["--script_path"],
"kwargs": {
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run.",
},
} ]
my_parser = argparse.ArgumentParser()
for i in jdata:
i["kwargs"]["type"] = eval(i["kwargs"]["type"])
my_parser.add_argument(*tuple(i["args"]), **i["kwargs"])
my_args = my_parser.parse_args() my_script_path = my_args.script_path
print(my_script_path)
注意:来自JSON文件的一些数据需要转换,例如类型需要转换为Python类型,然后才能传递给方法。
希望这对您有所帮助(您应该从我的评论中找到自己的出路)。
import argparse
import json
from pydoc import locate
# Load the json
f = open("args.json")
args = json.load(f)
# Pre-processing that converts "str" -> <class "str">, "int" -> <class "int">, etc.
for arg in args:
if "type" in arg.keys():
arg["type"] = locate(arg["type"])
my_parser = argparse.ArgumentParser()
# Normal method of arg-parse for comparision
my_parser.add_argument(
"-sp-normal",
"--script-path-normal",
nargs="?",
const="",
default="",
type=str,
help="The absolute path of the script to run.",
)
# Loading from the JSON
for arg in args:
my_parser.add_argument(*arg.pop("name_or_flags"), **arg)
# Load the args
my_args = my_parser.parse_args()
# Check
script_path = my_args.script_path
script_path_1 = my_args.script_path_1
script_path_normal = my_args.script_path_normal
print(script_path, script_path_1, script_path_normal)
我用的JSON:
[
{
"name_or_flags": [
"-sp",
"--script-path"
],
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run."
},
{
"name_or_flags": [
"-sp-1",
"--script-path-1"
],
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run."
}
]
我正在使用 argparse 指定一些参数如下:
my_parser = argparse.ArgumentParser()
my_parser.add_argument("--script_path", nargs='?', type=str, const='', default='', help="Path of the script to pull.")
my_parser.add_argument("--script", nargs='?', type=str, const='', default='', help="Name of the script to get pulled, without script extension.")
my_parser.add_argument("--project", nargs='?', type=str, const='', default='', help="Project.")
my_args = my_parser.parse_args()
my_script_path = my_args.script_path
my_script = my_args.script
my_project = my_args.project
现在我尝试做同样的事情,但不是通过我将加载的 .json 文件定义上述参数。我选择了 .json 因为它看起来不错,欢迎提出更好的建议。
我试过的是有一个像这样的 .json 文件:
[
{
"name_or_flags": ["-sp", "--script_path"],
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run."
},
...
]
加载文件后,我尝试了以下操作但失败了:
my_parser.add_argument(<combination of all keys, values from .json as a dictionary>)
my_parser.add_argument(<*unnamed_tup, **named_dict>)
#unnamed tuple since name_or_flags isn't supposed to be used
#unnamed tuple is only made from name_or_flags
无论我做什么都不行。
有没有人做过类似的事情?
我不想通过外部文件添加值,例如:
只是为了定义参数。
谢谢!
您需要pop("name_or_flags")
,注意始终提供列表;此外,您需要排除 type
,因为它会引发错误(是字符串而不是 class 或函数)。
import argparse
import json
args = json.loads("""
[{
"name_or_flags": "-sp", "--script_path"],
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run."
}]
""")
parser = argparse.ArgumentParser()
for arg in args:
arg.pop("type", None) # will raise ValueError: 'str' is not callable
parser.add_argument(*arg.pop("name_or_flags"), **arg)
# If the type is important to keep, you can always create a dictionary to map a string to a value, that is a builtin class.
mapping = dict(str=str, bool=bool, int=int) # this will map strings to classes
for arg in args:
thetype_str = arg.pop("type", "str")
arg["type"] = mapping.get(thetype_str, str) # if missing or wrong, will give plain string
parser.add_argument(*arg.pop("name_or_flags"), **arg)
这是从文件执行此操作的方法:
import argparse
jdata = [
{
"args": ["--script_path"],
"kwargs": {
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run.",
},
} ]
my_parser = argparse.ArgumentParser()
for i in jdata:
i["kwargs"]["type"] = eval(i["kwargs"]["type"])
my_parser.add_argument(*tuple(i["args"]), **i["kwargs"])
my_args = my_parser.parse_args() my_script_path = my_args.script_path
print(my_script_path)
注意:来自JSON文件的一些数据需要转换,例如类型需要转换为Python类型,然后才能传递给方法。
希望这对您有所帮助(您应该从我的评论中找到自己的出路)。
import argparse
import json
from pydoc import locate
# Load the json
f = open("args.json")
args = json.load(f)
# Pre-processing that converts "str" -> <class "str">, "int" -> <class "int">, etc.
for arg in args:
if "type" in arg.keys():
arg["type"] = locate(arg["type"])
my_parser = argparse.ArgumentParser()
# Normal method of arg-parse for comparision
my_parser.add_argument(
"-sp-normal",
"--script-path-normal",
nargs="?",
const="",
default="",
type=str,
help="The absolute path of the script to run.",
)
# Loading from the JSON
for arg in args:
my_parser.add_argument(*arg.pop("name_or_flags"), **arg)
# Load the args
my_args = my_parser.parse_args()
# Check
script_path = my_args.script_path
script_path_1 = my_args.script_path_1
script_path_normal = my_args.script_path_normal
print(script_path, script_path_1, script_path_normal)
我用的JSON:
[
{
"name_or_flags": [
"-sp",
"--script-path"
],
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run."
},
{
"name_or_flags": [
"-sp-1",
"--script-path-1"
],
"nargs": "?",
"const": "",
"default": "",
"type": "str",
"help": "The absolute path of the script to run."
}
]