【问题标题】:Using argparse to open a json file?使用 argparse 打开 json 文件?
【发布时间】:2020-10-14 20:39:34
【问题描述】:

我最近刚开始使用 argparse,我正在尝试使用它来打开一个 json 文件以及其他一些东西,比如输出到一个 csv 文件中。

import argparse
import os
import json
import csv
import pandas as pd

parser = argparse.ArgumentParser(description='Json to Csv')
parser.add_argument('file', type=argparse.FileType('r'))
#parser.add_argument('file', type=str)
args = parser.parse_args()

with args.file as json_data:

print(json_data)
#argparse_dict = vars(args)
#argparse_dict.update(json_data)


baseline_dict = {}
try:
    baseline_dict = json.load(json_data)
except:
    print("JSON Baseline File {}: Unable to LOAD")

results_dict = baseline_dict["results"]

"""with open(args.file) as json_data:
baseline_dict = {}
try:
    baseline_dict = json.load(json_data)
except:
    print("JSON Baseline File {}: Unable to LOAD")"""

#将新字典变成数据框 df = pd.DataFrame(results_dict)

当我尝试在终端中使用 argparse 打开 json 文件时,出现此错误。我知道它正在提取 json 文件,因为我可以在将其调用为 json_data 之前让它运行。

with args.file as json_data:
JSON Baseline File {}: Unable to LOAD
Traceback (most recent call last):

【问题讨论】:

  • 不是您当前问题的一部分,但您的整个for 循环毫无意义。如果您想要名为"results" 的键的值,只需执行results_dict = baseline_dict["results"](或results_dict = baseline_dict.get("results", {}),如果"results" 键可能不存在并且您想在这种情况下静默使用空dict)并删除所有从results_dict = {}del (baseline_dict) 的代码,其中有多个错误。
  • 放弃FileType使用;让argparse 给你一个文件名(字符串),然后你可以with open 并加载它。随着现代人对with open 的偏好,FileType 已经过时了。
  • @hpaulj:我不同意;让argparse 捕获异常并将其转换为对您有用的错误消息非常方便。当然,您需要自己添加with,但对于脚本(与库相反),您拥有顶级控制权,因此问题相当有限。
  • 请注意,是open 返回 的对象,而不是对open 本身的调用,它让with 语句确保它被关闭。
  • 尝试使用打开和不使用文件类型或使用文件类型并仅返回:JSON Baseline File {}: Unable to LOAD Traceback(最近一次调用最后一次):参见上面的编辑。

标签: python json csv argparse


【解决方案1】:

因为您使用argparse.FileType 作为参数type,所以args.file已经是一个打开的文件句柄,就好像它是由open 返回的一样。如果您想确保它确定性地关闭(并给它一个不合格的名称),您只需要:

with args.file as json_data:

或者只是:

with args.file:

如果不需要使用本地名称的别名。

【讨论】:

  • 所以当我最初在没有 argparse 的情况下打开文件时,我使用 json.load 没有问题,我做了你的建议,摆脱了以前的错误并使用:with args.file as json_data: but json.load (json_data) 不起作用
  • @YellowJacket:不要在没有解释的情况下在这里使用“不起作用”这个短语(使用minimal reproducible example);当我不知道除了“它错了”之外还有什么问题时,我真的不知道如何帮助你。
【解决方案2】:

可以通过两种方式加载文件的脚本:

import argparse, json

parser = argparse.ArgumentParser()
parser.add_argument('--file', type=argparse.FileType('r'))
parser.add_argument('--name')
args = parser.parse_args()
print(args)

if args.file is not None:
    print(json.load(args.file))
    args.file.close()
    
if args.name is not None:
    with open(args.name) as f:
         print(json.load(f))
         

样本运行:

1307:~/mypy$ python3 stack62557562.py 
Namespace(file=None, name=None)
1307:~/mypy$ python3 stack62557562.py --file foo.json
Namespace(file=<_io.TextIOWrapper name='foo.json' mode='r' encoding='UTF-8'>, name=None)
{'foo': 12, 'bar': 'twelve'}
1307:~/mypy$ python3 stack62557562.py --name foo.json
Namespace(file=None, name='foo.json')
{'foo': 12, 'bar': 'twelve'}
1307:~/mypy$ python3 stack62557562.py --name foo.json --file foo.json
Namespace(file=<_io.TextIOWrapper name='foo.json' mode='r' encoding='UTF-8'>, name='foo.json')
{'foo': 12, 'bar': 'twelve'}
{'foo': 12, 'bar': 'twelve'}

【讨论】:

  • 我完全尝试了您的解决方案,并为这两种解决方案获得了这个。 raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) 我应该为此在stackoverflow上提出一个新问题吗?
  • 如果我在打开的文件上尝试第二个json.load,我会收到该错误。第一个消耗整个文件,将其放在最后。
猜你喜欢
  • 2021-12-23
  • 2013-09-22
  • 1970-01-01
  • 2020-12-22
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 2012-07-20
  • 2020-05-10
相关资源
最近更新 更多