JSON загружается с ошибкой STDIN - PullRequest
0 голосов
/ 01 июля 2019

Я пытаюсь загрузить свой json-файл с помощью stdin, используя командную строку Windows: python algo.py < number.json и используя json.loads(sys.stdin) в моем скрипте, но это не удается.

Однако я могу загрузить свой JSON с

with open('number.json',encoding='utf-8-sig') as f:
n = json.loads(f)

Исключение повышается при использовании json.loads(sys.stdin):

the JSON object must be str, bytes or bytearray, not TextIOWrapper

Исключение повышается при использовании json.load(sys.stdin) or json.loads(sys.stdin.read()):

Expecting value: line 1 column 1 (char 0)

Кто-нибудь сталкивался с такой же проблемой? Я прочитал несколько сообщений в этом форуме, прежде чем попросить помощи.

Вот файл json:

[
  {
    "x": 1,
    "y": 4,
    "z": -1,
    "t": 2
  },
  {
    "x": 2,
    "y": -1,
    "z": 3,
    "t": 0
  }
]

1 Ответ

0 голосов
/ 01 июля 2019

Судя по вашим комментариям, ваша проблема в том, что к вашему файлу добавлена ​​ UTF-8 BOM . Это означает, что дополнительные три байта 0xEF 0xBB 0xBF находятся первыми в вашем файле.

Модуль Python json Документация говорит, что он не принимает спецификацию. Поэтому вы должны удалить его перед передачей данных JSON в json.load или json.loads.

Существует как минимум три способа удаления спецификации. Лучше всего просто отредактировать файл JSON, чтобы удалить его. Если это невозможно, вы можете пропустить это в своем коде Python.

Если ваш код нужен только для работы с файлами, содержащими спецификацию, вы можете использовать:

assert b'\xEF\xBB\xBF' == sys.stdin.buffer.read(3)

Это гарантирует, что удаленные байты действительно были спецификацией UTF-8.

Если вам нужно работать с файлами, которые могут содержать или не содержать спецификацию, вы можете заключить в стандартный поток ввода TextIOWrapper с правильной кодировкой, как указано в этого ответа . Тогда код выглядит так:

import io
stdin_wrapper = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8-sig')
# use stdin_wrapper instead of stdin

Цитировать Python Unicode HOWTO , почему utf-8-sig:

В некоторых областях также принято использовать «спецификацию» в начале файлов в кодировке UTF-8; имя вводит в заблуждение, поскольку UTF-8 не зависит от порядка байтов. Знак просто объявляет, что файл закодирован в UTF-8. Для чтения таких файлов используйте кодек utf-8-sig, чтобы автоматически пропустить метку, если она есть.

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