У меня есть файл JSON с именем myBlock.json:
{
"server": "https://abc.us",
"name":"XYZ",
"myData":"2019-04-08T15:43:05.810483Z",
"someFlg":"T",
"moreData":"k"
}
Я пытаюсь изменить это с новой информацией о дате и времени, поэтому
with open("myBlock.json") as json_data:
self.myBlockInfo = json.load(json_data)
origData = self.myBlockInfo["myData"]
origLine = '\"myData\":\"'+origData +'\",'
nowData = self.timeISO8601ZuluUTC()
newLine = '\"myData\":\"'+nowData+'\",'
with open("myBlock.json", "r+") as fh:
for line in fh.readlines():
if origLine in line:
print ("1-->", line)
str.replace(line, origLine, newLine)
print("2-->", line)
но не только строка та же, но и файл myBlock.Json остается прежним и не меняется?
Да, я пробовал, но когда я пишу это обратно, все форматирование испорчено.
это то, что вы разместили фактическое содержимое файла? Если это так, это неправильный JSON
Не могли бы вы опубликовать исходный и окончательный контент json? То, что вы пытаетесь сделать здесь, - это хромой обходной путь (гейнари). Я думаю, что это также подходит для XY-проблема. Если файл имеет тип json, прочитайте/запишите его как таковой.
Я отредактировал и добавил больше информации
Во-первых, вам не нужно экранировать двойные кавычки внутри одинарных кавычек. Я имею в виду, используйте это вместо этого:
origLine = '"myData":"'+origData +'",'
Затем более простой способ выполнить замену — заменить все содержимое файла вместо чтения построчно:
with open("myBlock.json", "r") as fh:
oldcontent = fh.read()
if origLine in oldcontent:
print("found!!")
newcontent = oldcontent.replace(origLine, newLine)
with open("newfile.json", "w") as fh:
fh.write(newcontent)
Но это не гарантирует работу! Я поставил if
в первый блок with
, чтобы помочь вам проверить, действительно ли существует то, что вы ожидаете. Скорее всего, входной JSON может содержать пробелы вокруг двоеточия, например "myData": "foobar"
, или даже новые строки вокруг двоеточия. Это все законные JSON. Вот почему кто-то в комментарии предложил вам прочитать JSON, изменить его и записать обратно JSON.
Если вы думаете, что обратная запись JSON испортит формат, попробуйте
newcontent = json.dumps(modified_data, indent=4)
indent=4
будет «красиво печатать» ваш JSON, вставляя соответствующий отступ, вероятно, сохраняя некоторое форматирование, которое вы ожидаете.
Вы можете редактировать файл следующим образом:
with open("myBlock.json", encoding = "utf-8") as json_data:
myBlockInfo = json.load(json_data)
origData = myBlockInfo["myData"]
origLine = '\"myData\":\"'+origData +'\",'
nowData = "asdsa"
newLine = '\"myData\":\"'+nowData+'\",'
myBlockInfo["myData"] = "sdfsd"
updated = open("myBlock.json", "w", encoding = "utf-8")
json.dump(myBlockInfo, updated)
Редактирование блока myBlockInfo["myData"]
напрямую и сохранение файла с помощью json.dump. Кроме того, вы можете использовать параметр кодирования, чтобы убедиться, что обе кодировки при чтении и записи одинаковы.
Спасибо, это именно то, что я сделал, но формат блока json изменился. и становится одной полной строкой. { "сервер": "abc.us", "имя": "XYZ", "myData": "2019-04-08T16:43:05.810483Z", "someFlg": "T", "moreData": "k" }
То, что вы ищете, это отступварг из [Питон 3]: json.свалка(obj, fp, *, skipkeys=False, sure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw):
If indent is a non-negative integer or string, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0, negative, or
""
will only insert newlines.None
(the default) selects the most compact representation. Using a positive integer indent indents that many spaces per level. If indent is a string (such as"\t"
), that string is used to indent each level.
код.py:
#!/usr/bin/env python3
import sys
import json
def main(argv):
with open("in.json") as inf:
obj = json.load(inf)
print("Original date:", obj["myData"])
# Modify obj["myData"] to whatever you need (self.timeISO8601ZuluUTC())
output_indent = int(argv[0]) if len(argv) and argv[0].isdecimal() else None
with open("out.json", "w") as outf:
json.dump(obj, outf, indent=output_indent)
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main(sys.argv[1:])
print("Done.")
Выход:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q055578224]> sopr.bat *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [prompt]> dir /b code.py in.json [prompt]> type in.json { "server": "https://abc.us", "name":"XYZ", "myData":"2019-04-08T15:43:05.810483Z", "someFlg":"T", "moreData":"k" } [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32 Original date: 2019-04-08T15:43:05.810483Z Done. [prompt]> dir /b code.py in.json out.json [prompt]> type out.json {"server": "https://abc.us", "name": "XYZ", "myData": "2019-04-08T15:43:05.810483Z", "someFlg": "T", "moreData": "k"} [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py 2 Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32 Original date: 2019-04-08T15:43:05.810483Z Done. [prompt]> dir /b code.py in.json out.json [prompt]> type out.json { "server": "https://abc.us", "name": "XYZ", "myData": "2019-04-08T15:43:05.810483Z", "someFlg": "T", "moreData": "k" }
Как видите, файл был хорошо переписан без необходимости изменения его исходного (текстового) содержимого.
Вы должны прочитать файл как строку json, загрузить его в словарь, изменить этот словарь с новым значением, записать словарь обратно в файл.