python - загрузка .json в словарь завершается неудачно - PullRequest
0 голосов
/ 25 марта 2019

Я пытаюсь загрузить все из файла .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, и наглядное пособие «показывает» мне, что оно рассматривает параметр словаря как нечто, что позже не используется, что также не имеет никакого смысла.

pycharm

Печать my_dict показывает {}. Я думаю, если бы я попытался вернуть параметр словаря в качестве значения в мой глобальный словарь, он бы работал (но сейчас я не хочу этого делать), но я хочу знать, почему вышеописанное не будет работать.

Есть идеи?

Спасибо

Ответы [ 3 ]

3 голосов
/ 25 марта 2019

Рассмотрим ваш код:

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 внутри функции. E.g.:

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"
}
1 голос
/ 25 марта 2019
import json

def load_data(path):
   with open(path,'r') as f:
      return json.load(f)
1 голос
/ 25 марта 2019

Кажется, вы ничего не возвращаете.

Попытка:

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'}

Обычно лучше, чтобы функция возвращала ответ, чем сохраняла его в глобальной переменной где-то вне области видимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...