Python:读取和写入文件时出现问题

时间:2020-05-07 10:07:13

标签: python file writing

我正在用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": []}

有人可以告诉我为什么会这样吗?

2 个答案:

答案 0 :(得分:2)

w+模式打开文件会将该文件截断,因此一旦尝试执行操作,便没有任何要读取的内容。此模式旨在让您返回并阅读打开文件后写的内容。

由于必须读取文件,因此需要以r模式打开文件。当您以后想要替换整个内容时,必须将其截断并以w模式打开。因此,请保留原始版本!

答案 1 :(得分:1)

正如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)