Python完美解决写入文件时删去最后一个字符

项目场景:

题主最近在写sql,因为每条语句存在大量重复字段,故考虑python脚本自动化生成sql代码,但是最后总是多一个逗号,有时候debug发现原因就出在忘记删这个结尾的逗号,故考虑想办法删掉结尾字符。


问题描述

这里拿一个最简单的场景举例,将输入的字符列表转成小写字符,并批量写出,最初的代码如下

stringlist = ["TEST1", "TEST2", "TEST3", "TEST4"]
def stringToLower(stringlist):
	with open('\path\to\txt','w',encoding='utf-8') as f:
		for i in range(len(stringlist)):
			tmp = stringlist[i]
			f.write(str(tmp)+","+"\n")
		f.close()
stringToLower(stringlist)

输出:
test1,
test2,
test3,
test4,

可以看到这样写的话结尾的字符串总会多一个,
这样在后续操作时每次都要手工删除一个逗号,如果忘记删除了可能会带来后续的一系列bug,所以能不能在脚本里面加上自动删除最后一个逗号呢?
题主先在网上搜索,看到了如下的解决方案:

import os

file_old = open('D:/EEG/LXP/FRAG1/FZ_H_ch5.txt', 'rb+')
n = 6

# 定位倒数第n个字符
file_old.seek(-n, os.SEEK_END)	
 
# 截断之后的数据 
file_old.truncate()  

file_old.close()

移动指针到倒数第n个字符,然后截断
于是简单的修改:

def stringToLower(stringlist):
	with open('\path\to\txt','w',encoding='utf-8') as f:
		for i in range(len(stringlist)):
			tmp = stringlist[i]
			f.write(str(tmp)+","+"\n")
		f.seek(-1, os.SEEK_END)
		f.truncate()
		f.close()

但是!!!!!!!!!!!!!出现如下报错

UnsupportedOperation: can't do nonzero end-relative seeks

网上查询,说必须将权限加上b
于是修改权限为'wb+',结果又报错

ValueError: binary mode doesn't take an encoding argument

很明显,和encoding编码又冲突了,删去encoding='utf-8',以为要成功了,好家伙,又报了新的错:

TypeError: a bytes-like object is required, not 'str'

很明显,不编码的话字符串根本都没法解析,编码的话又不支持binary mode,进而没法使用f.seek(),此时答主非常崩溃,这些错误仿佛形成了一个闭环,改来改去最后进了死胡同
但是我转念一想,如果我将写入操作和删除最后一个字符的操作分开,那么不就不矛盾了吗!
说干就干:

def stringToLower(stringlist):
	with open('\path\to\txt','w',encoding='utf-8') as f:
		for i in range(len(stringlist)):
			tmp = stringlist[i]
			f.write(str(tmp)+","+"\n")
		f.close()
	with open('\path\to\txt','rb+',encoding='utf-8') as f:
		f.seek(-1, os.SEEK_END)
		f.truncate()
		f.close()

很好,终于不报错了,但是当我打开输出的txt文档发现,最后一个逗号并没有删除掉(令人吐血),代码没有问题,那就是我的逻辑出问题了。再仔细看一下写入的代码,发现其实在逗号后面,还有一个换行符\n,那么把-1改成-2就行了吗?当然不行,在一行的末尾,其实是有两个字符\r \n一个是回车一个是换行,所以要改成-3才将指针移到逗号前面,
所以最后的代码如下:

def stringToLower(stringlist):
	with open('\path\to\txt','w',encoding='utf-8') as f:
		for i in range(len(stringlist)):
			tmp = stringlist[i]
			f.write(str(tmp)+","+"\n")
		f.close()
	with open('\path\to\txt','rb+',encoding='utf-8') as f:
		f.seek(-3, os.SEEK_END)
		f.truncate()
		f.close()

大功告成!

总结

刚开始写的时候,自以为是一个很微小的环节,没想到颇花了一番力气,网上的各种方法一定要结合自身的实际业务需要对症下药、灵活变通!

参考链接:https://blog.csdn.net/qq_38060391/article/details/115969966

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值