Python замена строки в файле не работает

У меня есть файл 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, загрузить его в словарь, изменить этот словарь с новым значением, записать словарь обратно в файл.

rdas 08.04.2019 19:01

Да, я пробовал, но когда я пишу это обратно, все форматирование испорчено.

Ghost 08.04.2019 19:02

это то, что вы разместили фактическое содержимое файла? Если это так, это неправильный JSON

rdas 08.04.2019 19:03

Не могли бы вы опубликовать исходный и окончательный контент json? То, что вы пытаетесь сделать здесь, - это хромой обходной путь (гейнари). Я думаю, что это также подходит для XY-проблема. Если файл имеет тип json, прочитайте/запишите его как таковой.

CristiFati 08.04.2019 19:06

Я отредактировал и добавил больше информации

Ghost 08.04.2019 19:40
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
87
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Во-первых, вам не нужно экранировать двойные кавычки внутри одинарных кавычек. Я имею в виду, используйте это вместо этого:

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

Ghost 08.04.2019 20:13

То, что вы ищете, это отступварг из [Питон 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"
}

Как видите, файл был хорошо переписан без необходимости изменения его исходного (текстового) содержимого.

Другие вопросы по теме