Python 语言及其应用 Chapter_6_Note 2 用write()写文本文件

本文介绍如何使用Python的write()和print()方法写入文本文件,包括整首诗的一次性写入、分块写入及避免重写已存在文件的方法。
使用write()写文本文件
下面这首作为
源数据:
>>> poem = '''There was a young lady named Bright,
... Whose speed was far faster than light;
... She started one day
... In a relative way,
... And returned on the previous night.'''
>>> len(poem)
150
以下代码将整首诗写到文件'relativity' 中:
>>> fout = open('relativity', 'wt')
>>> fout.write(poem)
150
>>> fout.close()
函数write() 返回写入文件的字节数。和print() 一样,它没有增加空格或者换行符。同
样,你也可以在一个文本文件中使用print():
>>> fout = open('relativity', 'wt')
>>> print(poem, file=fout)

>>> fout.close()

这就产生了一个问题:到底是使用write() 还是print() ? print() 默认会在每个参数后
面添加空格,在每行结束处添加换行。
在之前的例子中,它在文件relativity 中默认添
加了一个换行
。为了使print() 与write() 有同样的输出,传入下面两个参数。
• sep 分隔符:默认是一个空格' '
• end 结束字符:默认是一个换行符'\n'
除非自定义参数,否则print() 会使用默认参数。在这里,我们通过空字符串替换print()
添加的所有多余输出:
>>> fout = open('relativity', 'wt')
>>> print(poem, file=fout, sep='', end='')
>>> fout.close()
如果源字符串非常大,可以将数据分块,直到所有字符被写入:
>>> fout = open('relativity', 'wt')
>>> size = len(poem)
>>> offset = 0                              #这句话的意思是,起始位置从0开始写
>>> chunk = 100                        #以100字节大小为分隔界限
>>> while True:
... if offset > size:
... break
... fout.write(poem[offset:offset+chunk])       #第一次循环的时候,从0开始,写100,第二次开始循环的时候,从100开始写,剩下的。
... offset += chunk
...
100
50
>>> fout.close()

第一次写入100 个字符,然后写入剩下的50 个字符。
如果'relativity' 文件已经存在,使用模式x 可以避免重写文件:
>>> fout = open('relativity', 'xt')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileExistsError: [Errno 17] File exists: 'relativity'
可以加入一个异常处理:
>>> try:
... fout = open('relativity', 'xt')
... fout.write('stomp stomp stomp')
... except FileExistsError:
... print('relativity already exists!. That was a close one.')
...
relativity already exists!. That was a close one.


def extract_chapters(self): """从 .docx 中提取章节标题和内容""" try: print("【调试】开始提取章节...") doc = Document(self.file_path) full_text = "\n".join(para.text for para in doc.paragraphs) matches = list(CHAPTER_PATTERN.finditer(full_text)) if not matches: print("【调试】未匹配到任何章节标题") return [] chapters = [] for i in range(len(matches)): chapter_match = matches[i] chapter_title = chapter_match.group(1).strip() start = chapter_match.end() end = matches[i + 1].start() if i + 1 < len(matches) else len(full_text) content = full_text[start:end].strip() chapters.append((chapter_title, content)) print(f"【调试】提取到章节:{chapter_title}") return chapters except Exception as e: print("【错误】提取章节失败:", e) return [] def extract_subtitles_from_chapter(self, chapter_title, chapter_content): """从一个章节中提取所有 <标题> 和其内容""" print(f"【调试】正在处理章节:{chapter_title}") print(f"【调试】章节内容前100字:\n{chapter_content[:100]}") print("【调试】当前章节内容:\n", chapter_content[:300]) # 新增调试 results = [] last_end = 0 matches = SUBTITLE_PATTERN.findall(chapter_content) print("【调试】正则匹配结果:", matches) # 新增调试 for title, content in matches: if title.strip(): results.append({ '章节': chapter_title, '标题': title.strip(), '标题内容': content.strip() }) print(f" 【调试】提取到标题:{title}(长度:{len(content.strip())})") last_end = SUBTITLE_PATTERN.search(chapter_content, last_end).end() # 处理最后未匹配到标题的剩余内容(如果有的话) remaining = chapter_content[last_end:].strip() if remaining: print(f"【调试】章节末尾有剩余内容(长度:{len(remaining)}),忽略不处理") return results def convert_to_html(self, text): """将文本转为 HTML 格式""" html_lines = [f"<p>{line}</p>" if line.strip() else "<p> </p>" for line in text.split("\n")] return "\n".join(html_lines) def import_to_db(self): book_title = self.title_input.text().strip() if not book_title or not self.file_path: QMessageBox.warning(self, "输入错误", "请填书名并选择文件") return print("【调试】开始提取章节内容...") chapters = self.extract_chapters() print("【调试】共提取到章节数量:", len(chapters)) if not chapters: QMessageBox.warning(self, "内容错误", "未提取到任何章节内容") return try: conn = POOL_E.connection() if not conn: raise Exception("无法从连接池获取数据库连接") with conn: with conn.cursor() as cursor: cursor.execute("SELECT COUNT(*) AS count FROM 普通古籍 WHERE 书名=%s", (book_title,)) result = cursor.fetchone() count = result['count'] if result else 0 if count > 0: QMessageBox.warning(self, "警告", "该书已存在,避免重复导入") return print("【调试】开始逐个章节处理并插入数据库...") for chapter_title, chapter_content in chapters: subtitles = self.extract_subtitles_from_chapter(chapter_title, chapter_content) if not subtitles: print(f"【调试】章节 {chapter_title} 未提取到标题内容,插入章节内容") sql = """ INSERT INTO 普通古籍 (书名, 章节, 章节内容, 标题, 标题内容, 笔记, 图片路径) VALUES (%s, %s, %s, %s, %s, %s, %s) """ html_chapter_content = self.convert_to_html(chapter_content) data = [ ( book_title, chapter_title, html_chapter_content, '', # 标题为空 '', # 标题内容为空 html_chapter_content, # 笔记 '' # 图片路径留空 ) ] else: print(f"【调试】章节《{chapter_title}》提取到 {len(subtitles)} 个标题") sql = """ INSERT INTO 普通古籍 (书名, 章节, 章节内容, 标题, 标题内容, 笔记, 图片路径) VALUES (%s, %s, %s, %s, %s, %s, %s) """ data = [] for item in subtitles: html_content = self.convert_to_html(item['标题内容']) data.append(( book_title, item['章节'], None, # 章节内容为空,因为已有标题内容 item['标题'], html_content, html_content, # 笔记 '' # 图片路径留空 )) cursor.executemany(sql, data) conn.commit() print(f"【调试】章节《{chapter_title}》已插入 {len(data)} 条记录") QMessageBox.information(self, "成功", f"《{book_title}》已导入成功!") folder_path = f"D:/古籍信息/{book_title}" if not os.path.exists(folder_path): os.makedirs(folder_path) except Exception as e: print("【错误】导入失败:", e) QMessageBox.critical(self, "错误", f"导入失败: {str(e)}") try: conn.rollback() print("【调试】事务已回滚") except: pass 这里再提取转化的时候是不是没管可能存在的图片,我想前面提取章节内容和标题内容时把图片和文字都算进去,图片我已经设置好了资源路径book_folder = f"D:/古籍信息/{self.note_book_name}",
最新发布
09-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值