【问题标题】:Python: problem when reading and writing filePython:读写文件时出现问题
【发布时间】:2020-05-07 10:07:13
【问题描述】:

我正在用 Python 编写代码,需要通过 RFID 标签注册用户并将该记录写入文件。

我设法编写了一个运行良好的函数:

def register_user(self, rfid):

    with open(self._RECORDS_FILE_PATH, 'r') as infile:
        recordsData = json.load(infile)

    with open(self._RECORDS_FILE_PATH, 'w+') as outfile:
        newRecord = {
            "timestamp": int(round(time.time() * 1000)),
            "rfid": rfid
        }
        recordsData["recordsList"].insert(0, newRecord)
        json.dump(recordsData, outfile)

但我想尽可能优化代码并减少行数。 因此我决定使用w+,因为它应该能够同时读取和写入文件。

这是“优化”的代码:

def register_user(self, rfid):

    with open(self._RECORDS_FILE_PATH, 'w+') as file:
        recordsData = json.load(file)
        newRecord = {
            "timestamp": int(round(time.time() * 1000)),
            "rfid": rfid
        }
        recordsData["recordsList"].insert(0, newRecord)
        json.dump(recordsData, file)

“优化”代码不起作用,它给出了这个错误:

Traceback (most recent call last):
  File "/home/pi/accessControl/accessControlClasses/userInfoApi.py", line 57, in register_user_offline
    recordsData = json.load(outfile)
  File "/usr/lib/python2.7/json/__init__.py", line 291, in load
    **kw)
  File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

将保存记录的文件:

{"recordsList": []}

谁能告诉我为什么会这样?

【问题讨论】:

  • 检查userInfoApi.py中的第57行,您的程序无法加载recordsData = json.load(outfile)
  • 我稍微更改了上面代码中的行(在原始代码中它是“outfile”)。你知道为什么会这样吗?
  • 你能告诉我们文件格式吗?
  • optimise code as much as possible and reduce number of lines -- 糟糕,非常糟糕的主意。
  • 当您在 write 模式下打开时,您无法从文件中读取,因为它会被截断。阅读open(file, mode='r'...

标签: python file writing


【解决方案1】:

w+ 模式打开文件会截断它,因此一旦您尝试这样做,就没有什么可读取的了。此模式旨在让您在打开文件后返回并阅读您所写的内容。

由于您必须阅读该文件,您需要以r 模式打开它。由于您想稍后替换整个内容,因此您必须截断它并以w 模式打开它。所以,请继续使用您的原始版本!

【讨论】:

    【解决方案2】:

    正如 Thierry 所说,w+ 会截断文件——删除数据——因此没有可读取的数据。

    使用 other 读/写模式打开文件,r+ -- 其中句柄设置为文件的开头,并添加f.seek(0),您的代码将正常工作.

        with open(self._RECORDS_FILE_PATH, 'r+') as f:
            recordsData = json.load(f)
            newRecord = {
                "timestamp": int(round(time.time() * 1000)),
                "rfid": rfid
            }
            recordsData["recordsList"].insert(0, newRecord)
            f.seek(0) # go back to beginning of file 
            json.dump(recordsData, f)
    

    【讨论】:

    • 写入可能会出现问题,因为为了获得有效的 JSON 文件,OP 无论如何都必须删除原始内容并用新的内容替换它,这可能会更短- 所以无论如何都需要截断文件。
    • 你是对的,@ThierryLathuille。我在那里添加了f.seek(0)
    猜你喜欢
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多