'Use json overrides default argparse parameters
I have a argparse function containing a mix of internal and user specify settings. I want to use a json as configuration file to store user-specified parameters so that the json will be parsed back to this argparse function.
I also have a mix of data types in the parameters, they are defined in argparse but not in the json.
My argparse function looks like this
def parse_opt():
parser = argparse.ArgumentParser()
parser.add_argument('--name', nargs='+', type=str, default='experiment', help='project name') #specify by users
parser.add_argument('--visualise', action='store_true', help='output contains graphs') #specify by users
parser.add_argument('--imgsize', '--img', '--img-size', nargs='+', type=int, default=[640], help='image size h,w') #let users specify
parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='(optional) dataset.yaml path') #internal default setting
parser.add_argument('--thres', type=float, default=0.3, help='threshold') #internal default setting
opt = parser.parse_args()
return opt
My json configuration config.json looks like this, and it allows users to specify their parameters
d = {"name": "trial_001",
"visualise": true,
"imgsize": 1280}
I tried the following to pass new configurations using the script below, and ran into error TypeError: 'bool' object is not subscriptable . In the main() function, I want all default settings parsed as opt , then the three use user-defined parameters defined in config.json will override opt.name, opt.visualise and opt.imgsize. Then detect(**vars(opt)) reads all users and default parameters and apply detect() function to them (note: my detect() function isn't added in this post as it is quite long). Appreciate any pointers here. thanks.
import argparse
import json
def main(opt):
opt = parse_opt()
with open('config.json') as config_file:
d = json.loads(config_file.read())
for item in d.items():
args.extend(item)
detect(**vars(opt)) #detect() is a function that reads all variables from opt
if __name__ == "__main__":
main(opt)
EDIT: this is the full error message I encountered.
for item in d.items():
args.extend(item)
parser.parse_args(args)
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3326, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-26-53a113868d66>", line 1, in <module>
parser.parse_args(args)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py", line 1749, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py", line 1781, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py", line 1822, in _parse_known_args
option_tuple = self._parse_optional(arg_string)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py", line 2108, in _parse_optional
if not arg_string[0] in self.prefix_chars:
TypeError: 'bool' object is not subscriptable
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
