【问题标题】:python - load .json into dictionary failspython - 将.json加载到字典中失败
【发布时间】:2019-03-25 10:56:01
【问题描述】:

我正在尝试将所有内容从 .json 文件加载到 python 中的字典。

谁能向我解释为什么下面的方法不起作用?

my_dict = {}

def change_dict(str_file_path, dict_param):
  with open(str_file_path) as opened_file:
    dict_param = json.load(opened_file)
  opened_file.close

change_dict(my_file_path, my_dict)

我用于文件的路径是正确的,当我直接使用 my_dict 而不是使用字典参数时,上述方法有效(但这不是我想要做的)。

我一直在使用 Pycharm,视觉辅助工具“向我展示”它将字典参数视为以后不会使用的东西,这也没有任何意义。

打印 my_dict 显示 {} 。我想如果我尝试将字典参数作为值返回到我的全局字典中它会起作用(但现在我不想这样做)但我想知道为什么上面的方法不起作用。

有什么想法吗?

谢谢

【问题讨论】:

  • 只是一个旁注。不需要opened_file.close,因为您使用的是with open
  • 你想做什么?将 json 文件读入字典?如果是这样 - 请参阅我的答案。
  • 这一行 dict_param = json.load(opened_file) 仅将名称 dict_param 重新绑定到 change_dict() 函数范围内的新字典。您需要返回新的dict并分配给全局空间中的my_dict来更改它。
  • @SuperShoot,所以在change_dict(my_file_path, my_dict)my_dict 实际上不会“替换”参数?我不知道。我认为它会像一个变量一样。但话又说回来,如果我这样做dict_param["apple"] = "banana" 它会在我调用change_dict(my_file_path, my_dict) 并打印它时起作用。为什么会这样?

标签: python json file dictionary


【解决方案1】:

考虑你的代码:

my_dict = {}

def change_dict(str_file_path, dict_param):
  with open(str_file_path) as opened_file:
    dict_param = json.load(opened_file)  # **
  opened_file.close()

change_dict(my_file_path, my_dict)  # *

在 (*) 处,您传入了对 my_dict 的引用。这个“引用”只是一个存储my_dict地址的变量(如果你知道C/C++,这就像一个指针)。让我们将此称为“地址变量”A。注意,A 指向的内存块是my_dict,而不是对象本身。现在,在 (**) 处,您将这个“地址变量”/指针分配给 json.load(...) 返回的另一个内存块。它所做的只是将另一个地址写入这个“地址变量”/指针,而原始内存块(my_dict)保持不变。

但是,如果你不改变指针的值,而是调用一个函数来修改my_dict,比如update(),那么你可以在函数内部修改my_dict。例如:

import json

my_dict = {}


def change_dict(str_file_path, dict_param):
    with open(str_file_path) as opened_file:
        tmp = json.load(opened_file)
        dict_param.update(tmp)

change_dict('test.json', my_dict)
print(my_dict)

我的test.json 文件在哪里:

{
  "apple": "banana",
  "pineapple": "papaya"
}

【讨论】:

  • 就是这样!我将不得不更深入地了解细节,但这是有道理的。谢谢!
【解决方案2】:
import json

def load_data(path):
   with open(path,'r') as f:
      return json.load(f)

【讨论】:

    【解决方案3】:

    您似乎什么都没返回。

    试试:

    def change_dict(str_file_path):
      with open(str_file_path) as opened_file:
        dict_param = json.load(opened_file)
      return dict_param
    
    my_dict = change_dict(my_file_path)
    

    如果您坚持使用全局变量(在这种情况下是不好的做法),您可以尝试:

    dict_param = {}
    def change_dict(str_file_path):
      global dict_param
      with open(str_file_path) as opened_file:
        dict_param = json.load(opened_file)
    
    change_dict(my_file_path)
    

    请注意,如果您不返回值,您的函数会自动返回 None

    这是一个使用全局变量的简单示例:

    my_dict = {}
    
    def something(key, value):
        global my_dict
        my_dict[key] = value
    
    def something_else():
        global my_dict
        my_dict = {'c': 'd'}
    
    def non_global():
        my_dict = {'e': 'f'}
    
    something('a', 'b')
    print(my_dict)  ## outputs: {'a': 'b'}
    something_else()
    print(my_dict)  ## outputs: {'c': 'd'}
    non_global()
    print(my_dict)  ## outputs: {'c': 'd'}
    

    函数返回答案通常比将其存储在范围外的全局变量中更好。

    【讨论】:

    • 嘿,我试图从具有字典参数的函数中填充一些全局字典,以便我可以将字典“发送”到该函数作为输入。我认为您在上面对 global 所做的事情是不一样的,因为您正在跳过参数并直接填充它。您首先提到的返回方式有效,但有一种情况是字典会很大,我发现返回比仅仅“编辑”要慢。但根据答案,我认为我将不得不回去返回。
    • 好的,如果它解决了你的问题,记得点赞并接受答案。
    猜你喜欢
    • 2020-06-11
    • 2015-07-07
    • 2021-12-01
    • 2015-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    相关资源
    最近更新 更多