LINUX.ORG.RU

Работа с файлами типа json на python.

 ,


0

1

Как сделать , чтобы json.load(file) переводил не весь файл в объект, а определенное кол-во символов или определенное кол-во строк кода С КОНЦА?

Мне нужно по ключу вывести объект, только проблема в том, что у меня несколько одинаковых ключей в одном файле.

Вот пример файла:

{
«amount»: 2,
«hash»: «09fb1a1ec7fdd85386f728d7f4a19bcd»,
«name»: «ivan»,
«to_whom»: «katja»,
«uuid»: «7867857»
}

{
«amount»: 2,
«hash»: «39664a09322206aa658e9ab2cd5d63e4»,
«name»: «ivan»,
«to_whom»: «katja»,
«uuid»: «3242354»
}

Нужно напечатать, допустим, «uuid» последнего словаря.

P.s. Я новичок в программировании, поэтому, пожалуйста, не надо показывать какие вы умные. Если хотите помочь, то напишите как можно понятнее.

P.s. Была идея: прочитать и записать файл в переменную(пример: h), от этой переменной взять последние 163 символа(это размер словаря{}) (h[-163:]) и уже от этого найти json.loads(h)[«uuid»], но почему-то так не получилось.

Используй БД, например, sqlite и забудь уже про файлы.

vvn_black ★★★★★
()

Если хотите помочь, то напишите как можно понятнее.

Вариант помощи за вознаграждение рассматривается?

vvn_black ★★★★★
()

Твой файл – невалидный JSON. Поэтому напрямую с помощью json.load его не прочесть так, как тебе хочется. Можешь брать с конца файла по строке и ждать, пока не распарсится без ошибок. Модно, молодежно, неэффективно, вот это всё. А еще может на верхнем уровне сделать список из твоих объектов, тогда не будет проблем вытащить последний элемент стандартными средствами.

По символам: ты, возможно, не учел переводы строки. Это тоже символы.

lu4nik ★★★
()

1.После каждой '}' ставишь запятую.
2.Ставишь '[' в начале файла ']' в конце.
3.У тебя получается валидный json, парсишь его как обычно.
4.Берешь последний элемент массива.

от этой переменной взять последние 163 символа

Не надёжно.

P.s. Я новичок в программировании, поэтому, пожалуйста, не надо показывать какие вы умные.

Да да.

crutch_master ★★★★★
()

Был бы каждый объект записан в стоку, проблем бы не было, читал бы построчно и делал json.loads. А это ахинея какая-то, ни валидного JSON, ни адекватной записи.

Отформатируй пример файла нормально. Посмотрим, может быть, его хоть посплитить получится, если ты не контролируешь его содержимое.

Но лучше просто сделай валидный JSON или построчную запись объектов, в зависимости от потребностей.

WitcherGeralt ★★
()
Последнее исправление: WitcherGeralt (всего исправлений: 1)
Ответ на: комментарий от crutch_master

Как это сделать если словари у меня создаются автоматически?

def create_block(name, amount, to_whom, ):

data = {
‘name’: name,
‘amount’: amount,
‘to_whom’: to_whom,
‘hash’: prev_hash,
‘uuid’: uuid_block
}
with open(blockchain_dir + filename, ‘w’) as file:
json.dump(data, file, indent=4, sort_keys=True, ensure_ascii=False)
Если здесь после словаря поставить «,», то он будет записан в файл так […] Как эти скобки ставить в начале и в конце файла я не знаю. И разделять словари «,» тож не знаю как.

lil_rainnn
() автор топика

Судя по формату можно либо взять последние несколько 7 строк или вообще распарсить руками.

В питоне и то и то просто.

AntonI ★★★★★
()

indent=4[, sort_keys=True]

Убери эту ахинею, тогда сможешь читать построчно.

‘w’

Вот только как ты пишешь несколько объектов в файл, если у тебя файл открыт так, что он не должен дозаписываться? Ты, единожды открыв файл, за раз пишешь несколько объектов? Если да, то ты можешь просто сложить их в список и сериализовать уже его.

WitcherGeralt ★★
()
Последнее исправление: WitcherGeralt (всего исправлений: 1)

Два варианта на выбор: f(n) и g()

import json
import re

def f(n):
    'n - число строк с конца'
    with open('test.txt', 'r') as f: 
        return json.loads(' '.join(f.readlines()[:-n]))
    
def g():
    with open('test.txt', 'r') as f:
        return json.loads('[' + re.sub('}\s*{', '},{', f.read()) + ']')[-1]
    
print(f(8))
print(g())

Здесь не учитывается, что внутри json-строк могут быть фигурные скобки или символы начала строки, но, мне кажется, тебе это не важно. Если важно, напиши, я исправлю.

PS: Для корректной работы я заменил кавычки «» на " в файле. Не совсем понятно - это особенность разметки ЛОРа или твоего файла.

Marvel
()
Последнее исправление: Marvel (всего исправлений: 3)
Ответ на: комментарий от WitcherGeralt

У меня сделано так, если uuid какого-то файла совпадает с новым файлом, то в новый файл также записывается словарь из старого файла. Таким образом, у меня в 1 файл записываются 2-а словаря. При создании нового файла, опять идет сравнение uuid, вот здесь и выдается ошибка(потому что в файле 2- а словаря). И новый файл записывается только с новой информацией. Вот вся и проблема у меня, что он не дозаписывается.

lil_rainnn
() автор топика

на лоре есть разметка

abcq ★★
()

То что ты показал - это не JSON. Это могло быть двумя JSON’ами, но перестало быть таковым после склейки. Соответственно, JSON парсер парсить это вообще не должен. Решения:

  • Разделять обратно на json’ы руками. Например, если ты точно знаешь что объект занимает 7 строк, и \n ни в каких полях не встречается. Можно сразу с конца.
  • Не склеивать JSON’ы, а объединять в валидный JSON. Это будет выглядеть как-то так (кавычки лень заменять):
[
{
«amount»: 2,
«hash»: «09fb1a1ec7fdd85386f728d7f4a19bcd»,
«name»: «ivan»,
«to_whom»: «katja»,
«uuid»: «7867857»
}
,
{
«amount»: 2,
«hash»: «39664a09322206aa658e9ab2cd5d63e4»,
«name»: «ivan»,
«to_whom»: «katja»,
«uuid»: «3242354»
}
]
  • Писать свой парсер который умеет парсить конкатенацию json’ов
  • Взять готовый парсер который умеет конкатенированные json. YAJL умеет при указании соответствующего флага

последние 163 символа

Ты не знаешь что его размер 163 символа.

slovazap ★★★★★
()

Protobuf, avro и не долбаться с ручной сериализацией.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от Marvel
      А как сделать, чтобы результат работы выводился в таком же виде, какой я приводил в примере?                  
lil_rainnn
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.