Python游戏日志脚本重复写入相同用户名问题求助
问题根因
- 你当前的代码没有做用户名去重逻辑,每次触发
onPlayerJoin事件不管用户之前有没有记录过,都会直接写入新行,所以才会出现重复条目 - 另外原代码中
f.read(100)只读取文件前100个字节,就算你要做校验也只能覆盖前100字节的内容,无法全局判断是否存在重复
可选解决方案
方案1:每次写入前全量校验文件内容(适合记录量小的场景,不需要额外维护内存变量)
def onPlayerJoin(self, player): 'Called for new players joined' nick = player.getName(full=True).encode('utf-8') nick_str = str(nick) # 先读取所有已存的用户名 existing_nicks = set() try: with open(r"ALLIDS.txt", "r", encoding="utf-8") as f: for line in f: # 每行格式是 用户名: ,截取冒号前的部分做校验 if ':' in line: existing_nick = line.split(':', 1)[0].strip() existing_nicks.add(existing_nick) except FileNotFoundError: # 文件不存在说明还没有任何记录,直接往下走 pass # 只有当前用户名不存在时才写入 if nick_str not in existing_nicks: with open(r"ALLIDS.txt", "a+", encoding="utf-8") as f: # 判断文件是否为空,决定要不要加换行 f.seek(0) data = f.read() if len(data) > 0: f.write("\n") f.write(f"{nick_str}: ")
方案2:内存集合去重(性能更高,适合玩家量大的场景)
先在类的初始化方法中预加载已记录的用户名:
# 类的__init__方法里添加对应逻辑 def __init__(self): # 启动时先把已有的用户名加载到内存集合 self.recorded_players = set() try: with open(r"ALLIDS.txt", "r", encoding="utf-8") as f: for line in f: if ':' in line: nick = line.split(':', 1)[0].strip() self.recorded_players.add(nick) except FileNotFoundError: pass
再修改onPlayerJoin的逻辑:
def onPlayerJoin(self, player): 'Called for new players joined' nick = player.getName(full=True).encode('utf-8') nick_str = str(nick) # 直接查内存集合,不存在才写入 if nick_str not in self.recorded_players: with open(r"ALLIDS.txt", "a+", encoding="utf-8") as f: f.seek(0) data = f.read() if len(data) > 0: f.write("\n") f.write(f"{nick_str}: ") # 写入后把用户名加入集合,避免后续重复写入 self.recorded_players.add(nick_str)
其他优化提示
- 推荐统一用
with语句管理文件句柄,无需手动关闭文件,可避免资源泄漏 - 如果你的用户名包含特殊编码字符,注意统一文件读写的编码格式,避免出现乱码
- 如果不希望存储的用户名带
b''前缀,可以把str(nick)替换为nick.decode('utf-8'),直接存储解码后的明文用户名
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

