鱼C论坛

 找回密码
 立即注册
查看: 2908|回复: 13

[已解决]第29课:一个任务。视频中的例子

[复制链接]
发表于 2021-1-18 17:35:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 Peteryo01223 于 2021-1-18 17:41 编辑

问题来源:
第29课:一个任务。
视频中,小甲鱼写了个范例。

我照猫画虎,抄了一遍。
两个小区别:

1. 我命名的 f 盘文件是 record.txt。我本想删除后缀的.txt,但没成功。因此,读取的时候,只好写为
  1. open('F://record.txt.txt')
复制代码

2.  record.txt这个文件,我在论坛上没找到原始file,因此就自己写了一段类似,文字中间也用连续的等号隔开,结构与小甲鱼的例子一样,只不过中文内容换了。

但我的程序报错了,如下

  1. def save_file(boy, girl, count):
  2.     file_name_boy = 'boy_' + str(count) + '.txt'
  3.     file_name_girl = 'girl_' + str(count) + '.txt'

  4.     boy_file = open(file_name_boy, 'w')
  5.     girl_file = open(file_name_girl, 'w')

  6.     boy_file.writelines(boy)
  7.     girl_file.writelines(girl)

  8.     boy_file.close()
  9.     girl_file.close()

  10. def split_file(file_name):
  11.    
  12.     f = open('f://record.txt.txt')

  13.     boy = []
  14.     girl = []
  15.     count = 1

  16.     for each_line in f:
  17.         if each_line[:6] != '======':
  18.             (role, line_spoken) = each_line.split(':', 1)
  19.             if role == '小甲鱼':
  20.                 boy.append(line_spoken)
  21.             if role == '小客服':
  22.                 girl.append(line_spoken)

  23.         else:
  24.             save_file(boy, girl, count)
  25.             
  26.             boy = []
  27.             girl = []
  28.             count += 1
  29.             
  30.     save_file(boy, girl, count)

  31.     f.close()
复制代码

报错内容,如下。请问为何?非常感谢:
会不会因为,我的文件名里面,写了两遍.txt,导致后续都出现命名问题?
我想在文件名中删除 .txt(右击鼠标,重命名,删除,这么个步骤),但一直不成功。
  1. ================== RESTART: C:\Users\user\Desktop\20210118a.py =================
  2. Traceback (most recent call last):
  3.   File "C:\Users\user\Desktop\20210118a.py", line 41, in <module>
  4.     split_file('record.txt')
  5.   File "C:\Users\user\Desktop\20210118a.py", line 22, in split_file
  6.     for each_line in f:
  7. UnicodeDecodeError: 'gbk' codec can't decode byte 0x81 in position 20: illegal multibyte sequence
  8. >>>
复制代码
最佳答案
2021-1-19 10:18:25
本帖最后由 jackz007 于 2021-1-19 10:34 编辑
Peteryo01223 发表于 2021-1-19 09:37
为了,由浅入深,我先回溯一下。
我先在此抄写,第29课视频(旧),FishC 讲解到9分50秒的程序。如下。

...


        小甲鱼的代码是教学用的,考虑的都是理想条件,在容错性和代码精简方面不是很到位,这是我写的代码,楼主可以测试一下。
  1. def save(girl , boy , count):                                
  2.     file_name_boy = 'boy_' + str(count) + '.txt'                  # 输出文件与源代码同目录
  3.     file_name_girl = 'girl_' + str(count) + '.txt'                # 输出文件与源代码同目录
  4.     with open(file_name_boy , 'w') as boy_file:
  5.         boy_file . writelines(boy)
  6.     with open(file_name_girl , 'w') as girl_file:
  7.         girl_file . writelines(girl)   

  8. girl , boy , count = [] , [] , 1
  9. fp = open('record.txt' , encoding = 'UTF-8')                      # 为了减少干扰,'record.txt' 与源代码文件放到相同目录内。
  10. for each_line in fp:
  11.     if each_line . strip():                                       # 过滤空文本行
  12.         if each_line[:6] != '======':                             # 如果当前行是文本行
  13.             if ':' in each_line:                                  # 判断当前行是否可分割
  14.                 (role , line_spoken) = each_line . split(':', 1)  # 只对可分割行进行分割
  15.                 if role == '小甲鱼':
  16.                     boy . append(line_spoken)
  17.                 if role == '小客服':
  18.                     girl . append(line_spoken)
  19.             else:
  20.                 print(each_line)                                  # 把无法分割的行显示出来
  21.         else:
  22.             save(girl , boy , count)
  23.             count += 1
  24. fp . close()                                                      # 循环结束必须关闭文件
  25. save(girl , boy , count)                                           # 把列表中的信息写入文件
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-18 17:55:41 | 显示全部楼层
        文件编码问题
  1.     f = open('f://record.txt.txt')
复制代码

        这么改
  1.     f = open('f://record.txt.txt' , encoding = 'UTF-8')
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2021-1-18 18:03:44 | 显示全部楼层
jackz007 发表于 2021-1-18 17:55
文件编码问题

        这么改

改了,还是报错,python提示如下:
  1. Traceback (most recent call last):
  2.   File "C:\Users\user\Desktop\20210118a.py", line 41, in <module>
  3.     split_file('record.txt')
  4.   File "C:\Users\user\Desktop\20210118a.py", line 24, in split_file
  5.     (role, line_spoken) = each_line.split(':', 1)
  6. ValueError: not enough values to unpack (expected 2, got 1)
  7. >>>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-18 18:22:04 | 显示全部楼层
本帖最后由 jackz007 于 2021-1-18 19:39 编辑
Peteryo01223 发表于 2021-1-18 18:03
改了,还是报错,python提示如下:

  1.         if each_line[:6] != '======':                        # 如果这个文本开头 6 个字符不是 "="
  2.             (role, line_spoken) = each_line.split(':', 1)    # 那就根据文本行中的 ':' 字符对文本行进行一次分割,会分割出两个字符串,分别存入变量 role 和 line_spoken
复制代码

        文件 'record.txt' 中只能有两种行存在,一种由 6 个 '=' 开头的分隔行,另一种是正常的文本行,每个文本行必须至少有一个 ':' 字符。如果非分隔行中没有分割符 ':',那就属于第三种行。而文件中如果含有第三种行,就无法运行这个代码。
        目前你遇到的问题,就是遇到了第三种行,在已经被确定为文本行的字符串中,没有找到与 split() 中的分割符 ':' 相匹配的字符,导致无法对 each_line 进行分割,从而,无法对两个变量(role, line_spoken)进行赋值。
        用记事本打开 'record.txt' 检查一下,看看文本行中的 ':' 是全角的还是西文的,总之,必须要和 split() 里面的分隔符 ':' 一样才可以。 目前,split() 中的分隔符 ':' 是西文字符。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-18 19:37:02 | 显示全部楼层
标点符号要求是英文的,记事本里不好检查的,楼主可以把这个复制过去再试试
  1. 小客服:小甲鱼,今天有客户问你有没有女朋友?
  2. 小甲鱼:咦??
  3. 小客服:我跟她说你有女朋友了!
  4. 小甲鱼:。。。。。
  5. 小客服:她让你分手后考虑下她!然后我说“。。”
  6. 小甲鱼:然后呢?
  7. 小客服:她。。。。
  8. 小甲鱼:呃。。。你真牛逼!
  9. 小客服:那是,。。。
  10. 小甲鱼:下次有人想调戏你,我不阻止
  11. 小客服:滚!!
  12. ===========================================================================
  13. 小客服:小甲鱼,有个好评很好笑
  14. 小甲鱼:哦?
  15. 小客服:“有了小甲鱼,妈妈再也。。。。”
  16. 小甲鱼:哈哈哈,看到了,我还发了微博呢~
  17. 小客服:我看了你的微博呀!
  18. 小甲鱼:哟西~
  19. 小客服:那个回复“。。。。。。”
  20. 小甲鱼:T_T
  21. ============================================================================
  22. 小客服:小甲鱼,今天一个会员想找你
  23. 小甲鱼:哦?什么事儿?
  24. 小客服:他说你的一个学生月薪已经超过12k了
  25. 小甲鱼:哪里的?
  26. 小客服:上海的
  27. 小甲鱼:那正常,哪家公司的?
  28. 小客服:没说啊
  29. 小甲鱼:哦
  30. 小客服:老大,为什么我工资那么低啊,是时候涨工资了!!
  31. 小甲鱼:啊?你说什么?外面风大,听不见啊~~~~
  32. 小客服:滚!!!
复制代码

代码我之前加过注释,也放这儿了,
  1. #定义写入函数
  2. def save_file(boy,girl,count): #传入两个列表(用于存储对话内容)和一个计数器
  3.     file_name_boy='boy_'+str(count)+'.txt'  #新建一系列文件,命名由字符串拼接
  4.     file_name_girl='girl_'+str(count)+'.txt'#同理
  5.    
  6.     boy_file=open(file_name_boy,'w')  #以写入方式打开
  7.     girl_file=open(file_name_girl,'w') #同理
  8.    
  9.     boy_file.writelines(boy) #写入
  10.     girl_file.writelines(girl)
  11.    
  12.     boy_file.close()     #关闭
  13.     girl_file.close()
  14.    
  15. #定义切分函数   
  16. def spilt_file(file_name): #传入文件名
  17.         f = open(file_name,"r",encoding='UTF-8')
  18.            #关键点,编码方式                   就这里换个编码形式
  19.         boy=[]   
  20.         girl=[]
  21.         count=1   
  22.             
  23.         for each_line in f: #遍历原对话文件每一行
  24.             if each_line[:6]!='======':  #以分割线判断
  25.                 (role,line_spoken)=each_line.split(':',1)
  26.                 #以:为界,分成元组,进行1次操作
  27.                 if role =='小甲鱼': #根据名称(前三个字符)不同分别记入两个列表
  28.                     boy.append(line_spoken)
  29.                 if role =='小客服':
  30.                     girl.append(line_spoken)
  31.                     #到这一步,所有对话均被存入两列表
  32.             else:  #不是分割线的情况下,写入
  33.                 save_file(boy,girl,count) #调用写入,写入后清空列表,等待下次添加对话内容
  34.                
  35.                 boy=[]
  36.                 girl=[]
  37.                 count+=1     #count从2到3时跳出循环,所以文件里计数器count为3的那一对文件就缺少了
  38.             
  39.         save_file(boy,girl,count)  #第三段内容(上方for循环漏掉一次写入)
  40.         f.close()   
  41.         
  42. spilt_file('record.txt')  
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-19 08:42:33 | 显示全部楼层
本帖最后由 Peteryo01223 于 2021-1-19 09:14 编辑
昨非 发表于 2021-1-18 19:37
标点符号要求是英文的,记事本里不好检查的,楼主可以把这个复制过去再试试

代码我之前加过注释,也放这 ...


感谢指点。
不过,我这里还是报错。
我已经把你的文字,另存为 f 盘下的 record.txt 文件,这里没有重复后缀出现了。然后copy 你的代码,运行后,报错结果如下。感觉是不是我的文件读取路径,有问题?
  1. Traceback (most recent call last):
  2.   File "C:/Users/user/Desktop/20210119a.py", line 43, in <module>
  3.     spilt_file('record.txt')
  4.   File "C:/Users/user/Desktop/20210119a.py", line 18, in spilt_file
  5.     f = open(file_name,"r",encoding='UTF-8')
  6. FileNotFoundError: [Errno 2] No such file or directory: 'record.txt'
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-19 08:43:59 | 显示全部楼层
jackz007 发表于 2021-1-18 18:22
文件 'record.txt' 中只能有两种行存在,一种由 6 个 '=' 开头的分隔行,另一种是正常的文本 ...

感谢指点。如您所说,把中文 :,换为英文: 后,确实程序不报错了。
不过,运行后,什么也没发生。新的文件,没出现。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-19 09:14:58 From FishC Mobile | 显示全部楼层
Peteryo01223 发表于 2021-1-19 08:43
感谢指点。如您所说,把中文 :,换为英文: 后,确实程序不报错了。
不过,运行后,什么也没发生。新的 ...

理论上新的文件将会出现在你record的目录位置下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-19 09:17:23 From FishC Mobile | 显示全部楼层
Peteryo01223 发表于 2021-1-19 08:42
感谢指点。
不过,我这里还是报错。
我已经把你的文字,另存为 f 盘下的 record.txt 文件,这里没有 ...

record位置写的不对,你的文件放在哪儿就这哪儿就好,我是放在.py的同目录下的,你要嫌麻烦大可放到一起去,然后我的代码就应该没问题了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-19 09:37:36 | 显示全部楼层
为了,由浅入深,我先回溯一下。
我先在此抄写,第29课视频(旧),FishC 讲解到9分50秒的程序。如下。
  1. f = open('f://record.txt')

  2. boy = []
  3. girl = []
  4. count = 1

  5. for each_line in f:
  6.     if each_line[:6] != '======':
  7.         (role, line_spoken) = each_line.split(':', 1) # 分割字符串
  8.         if role == '小甲鱼':
  9.             boy.append(line_spoken)
  10.         if role == '小客服':
  11.             girl.append(line_spoken)
  12.         
  13.     else:
  14.         file_name_boy = 'boy_' + str(count) + '.txt'
  15.         file_name_girl = 'girl_' + str(count) + '.txt'
  16.         # 对文件命名

  17.         boy_file = open(file_name_boy, 'w')
  18.         girl_file = open(file_name_girl, 'w')
  19.         # 打开刚命名的文件,同时进入可以书写的模式

  20.         boy_file.writelines(boy)
  21.         girl_file.writelines(girl)

  22.         boy_file.close()
  23.         girl_file.close()

  24.         boy = [] # 初始化,列表清空,为下一个文档存储做好准备
  25.         girl = [] # 初始化,列表清空,为下一个文档存储做好准备
  26.         count += 1

  27. f.close()
复制代码


运行后,报错如下:
  1. Traceback (most recent call last):
  2.   File "C:/Users/user/Desktop/20210119a.py", line 7, in <module>
  3.     for each_line in f:
  4. UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 4: illegal multibyte sequence
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-19 10:18:25 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2021-1-19 10:34 编辑
Peteryo01223 发表于 2021-1-19 09:37
为了,由浅入深,我先回溯一下。
我先在此抄写,第29课视频(旧),FishC 讲解到9分50秒的程序。如下。

...


        小甲鱼的代码是教学用的,考虑的都是理想条件,在容错性和代码精简方面不是很到位,这是我写的代码,楼主可以测试一下。
  1. def save(girl , boy , count):                                
  2.     file_name_boy = 'boy_' + str(count) + '.txt'                  # 输出文件与源代码同目录
  3.     file_name_girl = 'girl_' + str(count) + '.txt'                # 输出文件与源代码同目录
  4.     with open(file_name_boy , 'w') as boy_file:
  5.         boy_file . writelines(boy)
  6.     with open(file_name_girl , 'w') as girl_file:
  7.         girl_file . writelines(girl)   

  8. girl , boy , count = [] , [] , 1
  9. fp = open('record.txt' , encoding = 'UTF-8')                      # 为了减少干扰,'record.txt' 与源代码文件放到相同目录内。
  10. for each_line in fp:
  11.     if each_line . strip():                                       # 过滤空文本行
  12.         if each_line[:6] != '======':                             # 如果当前行是文本行
  13.             if ':' in each_line:                                  # 判断当前行是否可分割
  14.                 (role , line_spoken) = each_line . split(':', 1)  # 只对可分割行进行分割
  15.                 if role == '小甲鱼':
  16.                     boy . append(line_spoken)
  17.                 if role == '小客服':
  18.                     girl . append(line_spoken)
  19.             else:
  20.                 print(each_line)                                  # 把无法分割的行显示出来
  21.         else:
  22.             save(girl , boy , count)
  23.             count += 1
  24. fp . close()                                                      # 循环结束必须关闭文件
  25. save(girl , boy , count)                                           # 把列表中的信息写入文件
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-19 10:24:29 | 显示全部楼层
jackz007 发表于 2021-1-18 17:55
文件编码问题

        这么改


这个方法,挺管用的,每次这么写,都不会报错。
  1. [code]f = open('f://record.txt', encoding = 'UTF-8')
复制代码

不过,就是文件夹里,还是没有任何新文件产生出来。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-19 10:28:16 | 显示全部楼层
jackz007 发表于 2021-1-19 10:18
小甲鱼的代码是教学用的,考虑的都是理想条件,在容错性和代码精简方面不是很到位,这是我写的 ...

牛人!成功了!
(有几个girl拼写少了最后的字母 l,有个 open 重复写了两遍。但是瑕不掩瑜,你还是太强!)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-19 10:29:49 | 显示全部楼层
昨非 发表于 2021-1-19 09:17
record位置写的不对,你的文件放在哪儿就这哪儿就好,我是放在.py的同目录下的,你要嫌麻烦大可放到一起 ...

多谢高人指点。我又欠你一个最佳,我记着。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-26 15:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表