Python:如何从 JSON 文件中获取参数?
Python: how can I ingest arguments from JSON file?
我有一个 python 代码块可以获取命令行参数,例如:
import argparse
if __name__ == "__main__": # myScript.py
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--int", help="Int with default", type=int, default=20)
parser.add_argument("-swd", "--strwdef", help="string with default", type=str, default="DEFAULTSTRING")
parser.add_argument("-snd", "--strnodef", help="string without default", type=str)
parser.add_argument("-f", "--flag", help="binary flag", action='store_true')
args = parser.parse_args()
i = args.i
swd = args.swd
snd = args.snd
f = args.flag
所以这适用于这样的命令:
python myScript.py -swd SomeString --int 35 -f
我想改为从 JSON 文件中读取这些参数。问题:
python 2.7
中是否有内置功能来设置它,而不是编写我自己的 json.load()
解析结果的自定义代码来处理参数类型、默认值等?
- 如果有,上例 JSON 文件的正确格式是什么,以及填充变量
i
、swd
等的方法是什么?
谢谢!
下面是您可以做到这一点的方法。我不确定它有多安全。 JSON 键应该与您需要将它们解析成的变量相同。
j = json.loads(...)
print j # {'swd': 'someString', 'i': 35}
locals().update(j)
print swd, i # someString 35
docs for locals 建议不要修改,因此使用它需要您自担风险。
我很快想到的一个更安全的解决方法是将 argparsing 后的结果存储到字典中。从 JSON 导入它们时,只需单独更新该字典。
来自解析器的 args
是一个 argparse.Namespace
对象,with 很容易变成一个字典 with
vars(args)
-swd SomeString --int 35 -f
然后会产生类似 namespace(swd='SomeString', int=35, f=True)
和 {'swd':'SomeString', 'int':35, 'f':True}
.
的东西
等价的 JSON 将解码为类似的字典。
可以将字典转换(返回)为命名空间:
In [2]: dd={'swd':'SomeString', 'int':35, 'f':True}
In [3]: dd
Out[3]: {'f': True, 'int': 35, 'swd': 'SomeString'}
In [4]: argparse.Namespace(**dd)
Out[4]: Namespace(f=True, int=35, swd='SomeString')
据我所知,没有一个包可以像推理字典一样应用 argparse
(可能是由 json.loads
创建的)。
最近有人问是否有一种方法可以根据 namespace
重新创建 sys.argv
字符串。你可能会查一下。
我可以用这段代码重新创建一个 sys.argv
喜欢的列表
In [22]: def foo(k,v):
if len(k)==1:
k = '-'+k
else:
k = '--'+k
if isinstance(v,bool):
return (k,)
else:
return k,str(v)
....:
In [23]: argv=[]
In [24]: for k,v in dd.items():
argv.extend(foo(k,v))
....:
In [25]: argv
Out[25]: ['-f', '--int', '35', '--swd', 'SomeString']
然后可以将其传递给您的解析器:
args = parser.parse_args(argv)
========================
您可以做的另一件事是创建一个具有默认值的字典,并从 JSON 字典更新它:
In [27]: defaultd=dict(int=20, strwdef='DEFAULTSTRING',snd=None,flag=False)
In [28]: defaultd
Out[28]: {'strwdef': 'DEFAULTSTRING', 'snd': None, 'int': 20, 'flag': False}
In [29]: defaultd.update(dd)
In [30]: defaultd
Out[30]:
{'strwdef': 'DEFAULTSTRING',
'f': True,
'flag': False,
'swd': 'SomeString',
'snd': None,
'int': 35}
我刚刚注意到一个问题。对于 defaultd
我使用了长名称 'flag' 名称,但在 JSON dict 中我使用了短名称 'f'。
我可以有选择地从 JSON 字典中复制,例如:
In [32]: for k in defaultd:
....: if k in dd:
....: defaultd[k]=dd[k]
....:
In [33]: defaultd
Out[33]: {'strwdef': 'DEFAULTSTRING', 'snd': None, 'int': 35, 'flag': False}
处理 'bad' 值或别名会更复杂。
我有一个 python 代码块可以获取命令行参数,例如:
import argparse
if __name__ == "__main__": # myScript.py
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--int", help="Int with default", type=int, default=20)
parser.add_argument("-swd", "--strwdef", help="string with default", type=str, default="DEFAULTSTRING")
parser.add_argument("-snd", "--strnodef", help="string without default", type=str)
parser.add_argument("-f", "--flag", help="binary flag", action='store_true')
args = parser.parse_args()
i = args.i
swd = args.swd
snd = args.snd
f = args.flag
所以这适用于这样的命令:
python myScript.py -swd SomeString --int 35 -f
我想改为从 JSON 文件中读取这些参数。问题:
python 2.7
中是否有内置功能来设置它,而不是编写我自己的json.load()
解析结果的自定义代码来处理参数类型、默认值等?- 如果有,上例 JSON 文件的正确格式是什么,以及填充变量
i
、swd
等的方法是什么?
谢谢!
下面是您可以做到这一点的方法。我不确定它有多安全。 JSON 键应该与您需要将它们解析成的变量相同。
j = json.loads(...)
print j # {'swd': 'someString', 'i': 35}
locals().update(j)
print swd, i # someString 35
docs for locals 建议不要修改,因此使用它需要您自担风险。
我很快想到的一个更安全的解决方法是将 argparsing 后的结果存储到字典中。从 JSON 导入它们时,只需单独更新该字典。
args
是一个 argparse.Namespace
对象,with 很容易变成一个字典 with
vars(args)
-swd SomeString --int 35 -f
然后会产生类似 namespace(swd='SomeString', int=35, f=True)
和 {'swd':'SomeString', 'int':35, 'f':True}
.
等价的 JSON 将解码为类似的字典。
可以将字典转换(返回)为命名空间:
In [2]: dd={'swd':'SomeString', 'int':35, 'f':True}
In [3]: dd
Out[3]: {'f': True, 'int': 35, 'swd': 'SomeString'}
In [4]: argparse.Namespace(**dd)
Out[4]: Namespace(f=True, int=35, swd='SomeString')
据我所知,没有一个包可以像推理字典一样应用 argparse
(可能是由 json.loads
创建的)。
最近有人问是否有一种方法可以根据 namespace
重新创建 sys.argv
字符串。你可能会查一下。
我可以用这段代码重新创建一个 sys.argv
喜欢的列表
In [22]: def foo(k,v):
if len(k)==1:
k = '-'+k
else:
k = '--'+k
if isinstance(v,bool):
return (k,)
else:
return k,str(v)
....:
In [23]: argv=[]
In [24]: for k,v in dd.items():
argv.extend(foo(k,v))
....:
In [25]: argv
Out[25]: ['-f', '--int', '35', '--swd', 'SomeString']
然后可以将其传递给您的解析器:
args = parser.parse_args(argv)
========================
您可以做的另一件事是创建一个具有默认值的字典,并从 JSON 字典更新它:
In [27]: defaultd=dict(int=20, strwdef='DEFAULTSTRING',snd=None,flag=False)
In [28]: defaultd
Out[28]: {'strwdef': 'DEFAULTSTRING', 'snd': None, 'int': 20, 'flag': False}
In [29]: defaultd.update(dd)
In [30]: defaultd
Out[30]:
{'strwdef': 'DEFAULTSTRING',
'f': True,
'flag': False,
'swd': 'SomeString',
'snd': None,
'int': 35}
我刚刚注意到一个问题。对于 defaultd
我使用了长名称 'flag' 名称,但在 JSON dict 中我使用了短名称 'f'。
我可以有选择地从 JSON 字典中复制,例如:
In [32]: for k in defaultd:
....: if k in dd:
....: defaultd[k]=dd[k]
....:
In [33]: defaultd
Out[33]: {'strwdef': 'DEFAULTSTRING', 'snd': None, 'int': 35, 'flag': False}
处理 'bad' 值或别名会更复杂。