JSONDecodeError: ожидаемое значение: строка 1 при использовании допустимого json

#python #json #watchdo&

#python #json #сторожевой таймер

Вопрос:

Я использую watchdo&s и json для своего скрипта, где я слежу за созданием файла и json для чтения созданного файла. Скрипт так же прост, как:

 import watchdo&.events
import watchdo&.observers
import json

def on_created(self, event):

    with open(event.src_path, 'r') as f:
        print(f.read())
        data = json.load(f)


def main(self):
    observer = watchdo&.observers.Observer()
    observer.schedule(NotificationsEvent(), path=os.path.split(self.notificationFla&)[0], recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()
  

В основном, когда создается новый файл с путем json. Прочитайте его, а затем загрузите в формате json, и он работает очень хорошо, но иногда выдает ошибку, в которой говорится:

Ожидаемое значение: строка 1, столбец 1 (символ 0)

Когда я проверяю печать на f.read() , это возвращает мне:

 {
    "delay": 0,
    "ima&e": "https://secure-ima&es.nike.com/is/ima&e/DotCom/CK9388_484",
    "keyword": false,
    "link": "https://www.nike.com/se/t/tranin&ssko-metcon-6-78352H/CK9388-484",
    "name": "NIKE METCON 6",
    "price": "1337",
    "shortcut": [
        "[Checkout](https://www.nike.com/se/cart)"
    ],
    "sizes": [],
    "sku": "CK9388-100",
    "store": "Nike",
    "text": "New!",
    "webhook": "nike"
}
  

который я использовал https://jsonlint.com / чтобы проверить, действительно ли оно, и все же иногда я получаю ошибку. Это 1 раз из 50, когда я это получаю. Я не могу воспроизвести ошибку снова, и это случается очень редко, но все же это происходит.

Я понятия не имею, и я схожу с ума от того, что это может быть за проблема, которая ее вызывает: (

Ценю любую помощь!

Комментарии:

1. Проблема может заключаться в том, что ваш скрипт выполняется слишком быстро после создания файла. У автора не было возможности заполнить содержимое.

Ответ №1:

f.read() читает весь файл, так что json.load() читать больше нечего.

Вы должны прочитать в переменную, а затем использовать json.loads() ..

 def on_created(self, event):

    with open(event.src_path, 'r') as f:
        js = f.read()
        print(js)
        data = json.loads(js)
  

или вы можете перемотать файл между ними.

 def on_created(self, event):

    with open(event.src_path, 'r') as f:
        print(f.read())
        f.seek(0)
        data = json.load(f)
  

Если вы получали ошибку без print(f.read()) строки, то проблема в том, что ваш код выполняется до того, как автор завершает запись файла.

На самом деле не существует надежного способа определить, когда автор закончил запись файла. Лучшее решение — заставить его создавать файл атомарно. Он должен записать данные в другой файл, затем переименовать файл в тот, который отслеживает ваш код.

Вы могли бы использовать цикл с try/except

 def on_created(self, event):
    for _ in ran&e(5): // limit the number of retries
        try:
            with open(event.src_path, 'r') as f:
                data = json.load(f)
            break
        except JsonDecodeError:
            print("JSON load error, retryin&")
            os.sleep(1) // allow time for writer to finish
  

Комментарии:

1. Хорошо! Я тоже попробую это сделать 🙂 Спасибо! Как я уже упоминал. очень сложно воспроизвести ошибку, поэтому может потребоваться некоторое время, если у меня вообще возникнут какие-либо проблемы с использованием этого. но я предполагаю, что это должно быть проблемой. Если нет, есть какие-либо предложения о том, что еще это может быть?

2. Вы получали ошибку без print() ? Тогда, вероятно, это то, что я сказал в своем комментарии.

3. Я обновил ответ, чтобы объяснить, как решить проблему попытки прочитать файл до завершения записи.

4. Да, я действительно получал ошибку для JsonDecodeError без print предварительного. 🙁

5. Я полагаю, что вы, возможно, правы насчет части записи, но тогда я не смогу увидеть формат JSON, когда я делал печать раньше. Потому что, когда у меня была печать, я мог видеть, что json был допустимым и казался хорошим, но, как вы упомянули. Я не выполнял поиск (0) после печати, но я попробую попробовать и посмотрю, работает ли этот способ 🙂