【问题标题】:Python 3: Idiomatic way to delete last char in filePython 3:删除文件中最后一个字符的惯用方法
【发布时间】:2019-06-27 09:17:36
【问题描述】:

有没有一种惯用的方法来做到这一点?我刚刚从 Python 2 升级到 Python 3,我正在尝试移植我的脚本,我不得不说我没有留下深刻的印象。据我所知,我的代码可以运行了

从这里

# Not allowed by Python 3 anymore without being in binary mode.
card_names_file.seek(-1, os.SEEK_END)
if card_names_file.read() == ',':
    card_names_file.truncate()

到这里

# Go to end of file just to get position index. lawl.
card_names_file.seek(0, os.SEEK_END)
# Create a temporary just to store said index. More lawl.
eof = card_names_file.tell()
# Index one from the back. ugh. w/e, that's fine.
card_names_file.seek(eof - 1, os.SEEK_SET)

# Oh wait, .read() will advance my pointer. Oh hey Python 3 doesn't let me
# use .peek() either. Fantastic. I'll have to read this...
if card_names_file.read() == ',':
    # Then go back to where I was by indexing from front AGAIN
    card_names_file.seek(eof - 1, os.SEEK_SET)
    # Then remove last character.
    card_names_file.truncate()

这是我几乎见过的最愚蠢的代码,到目前为止我已经花了 2 个半小时试图从文件后面删除一个字符,这看起来像是一个 hack。

另一种方法是我的代码看起来像这样

# open file
with open(file, a+)
    # do stuff

# open same file
with open(file, w+b)
    # do different stuff

但我实际上也无法让它工作。

【问题讨论】:

  • 您的第一个 sn-p 已失败。 card_names_file.truncate() 什么都不做,因为你已经在文件的末尾了。
  • 我也很确定 seek 函数总是在字节上运行,所以你的代码也从来没有真正在 python 2 中工作过。
  • @aran 它确实有效,所以也许在 Pyhton 2 .read 没有推进指针。 @snakecharmerb,我肯定已经阅读了整个帖子,它没有回答我的问题。您会注意到所选答案在 Python 3 中根本不起作用,其中一个 i 就像 30 行代码。不用了。
  • 它可能看起来像代码可以工作,因为您的文件使用了逗号被编码为单个字节的编码。如果存在逗号由超过 1 个字节表示的编码,或者另一个多字节字符包含一个看起来像逗号的字节,那么您的代码肯定无法正常工作。

标签: python python-3.x file readfile truncate


【解决方案1】:

底层缓冲区确实有一个您正在寻找的peek() 方法,所以:

f = open('FILE', 'a+')
f.seek(f.seek(0, os.SEEK_END) - 1)
# or with the same effect you can also:
os.lseek(f.fileno(), -1, os.SEEK_END)
# Actually in append mode we could just seek by -1 from where we are
# (cursor at the end after opening)
f.tell()  # just to see...
f.buffer.peek(1)
f.tell()  # ...still where we were

或者,您也可以使用os.pread()。例如:

os.pread(f.fileno(), 1, os.fstat(f.fileno()).st_size - 1)

这并不像依赖更高级别的抽象访问文件那样惯用,但我会invoke“虽然实用性胜过纯度。”

【讨论】:

  • 这很有效,而且它的代码量与我的 Python 2 impl 几乎相同。太感谢了!我不知道底层缓冲区。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2010-12-20
  • 2012-05-23
  • 2017-01-29
  • 2013-09-22
  • 2021-08-21
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
相关资源
最近更新 更多