Peteryo01223 发表于 2021-1-18 17:35:01

第29课:一个任务。视频中的例子

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

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

我照猫画虎,抄了一遍。
两个小区别:
1. 我命名的 f 盘文件是 record.txt。我本想删除后缀的.txt,但没成功。因此,读取的时候,只好写为
open('F://record.txt.txt')
2.record.txt这个文件,我在论坛上没找到原始file,因此就自己写了一段类似,文字中间也用连续的等号隔开,结构与小甲鱼的例子一样,只不过中文内容换了。

但我的程序报错了,如下

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

    boy_file = open(file_name_boy, 'w')
    girl_file = open(file_name_girl, 'w')

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

    boy_file.close()
    girl_file.close()

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

    boy = []
    girl = []
    count = 1

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

      else:
            save_file(boy, girl, count)
            
            boy = []
            girl = []
            count += 1
            
    save_file(boy, girl, count)

    f.close()
报错内容,如下。请问为何?非常感谢:
会不会因为,我的文件名里面,写了两遍.txt,导致后续都出现命名问题?
我想在文件名中删除 .txt(右击鼠标,重命名,删除,这么个步骤),但一直不成功。
================== RESTART: C:\Users\user\Desktop\20210118a.py =================
Traceback (most recent call last):
File "C:\Users\user\Desktop\20210118a.py", line 41, in <module>
    split_file('record.txt')
File "C:\Users\user\Desktop\20210118a.py", line 22, in split_file
    for each_line in f:
UnicodeDecodeError: 'gbk' codec can't decode byte 0x81 in position 20: illegal multibyte sequence
>>>

jackz007 发表于 2021-1-18 17:55:41

      文件编码问题
    f = open('f://record.txt.txt')
      这么改
    f = open('f://record.txt.txt' , encoding = 'UTF-8')

Peteryo01223 发表于 2021-1-18 18:03:44

jackz007 发表于 2021-1-18 17:55
文件编码问题

      这么改

改了,还是报错,python提示如下:
Traceback (most recent call last):
File "C:\Users\user\Desktop\20210118a.py", line 41, in <module>
    split_file('record.txt')
File "C:\Users\user\Desktop\20210118a.py", line 24, in split_file
    (role, line_spoken) = each_line.split(':', 1)
ValueError: not enough values to unpack (expected 2, got 1)
>>>

jackz007 发表于 2021-1-18 18:22:04

本帖最后由 jackz007 于 2021-1-18 19:39 编辑

Peteryo01223 发表于 2021-1-18 18:03
改了,还是报错,python提示如下:

      if each_line[:6] != '======':                        # 如果这个文本开头 6 个字符不是 "="
            (role, line_spoken) = each_line.split(':', 1)    # 那就根据文本行中的 ':' 字符对文本行进行一次分割,会分割出两个字符串,分别存入变量 role 和 line_spoken
      文件 'record.txt' 中只能有两种行存在,一种由 6 个 '=' 开头的分隔行,另一种是正常的文本行,每个文本行必须至少有一个 ':' 字符。如果非分隔行中没有分割符 ':',那就属于第三种行。而文件中如果含有第三种行,就无法运行这个代码。
      目前你遇到的问题,就是遇到了第三种行,在已经被确定为文本行的字符串中,没有找到与 split() 中的分割符 ':' 相匹配的字符,导致无法对 each_line 进行分割,从而,无法对两个变量(role, line_spoken)进行赋值。
      用记事本打开 'record.txt' 检查一下,看看文本行中的 ':' 是全角的还是西文的,总之,必须要和 split() 里面的分隔符 ':' 一样才可以。 目前,split() 中的分隔符 ':' 是西文字符。

昨非 发表于 2021-1-18 19:37:02

标点符号要求是英文的,记事本里不好检查的,楼主可以把这个复制过去再试试
小客服:小甲鱼,今天有客户问你有没有女朋友?
小甲鱼:咦??
小客服:我跟她说你有女朋友了!
小甲鱼:。。。。。
小客服:她让你分手后考虑下她!然后我说“。。”
小甲鱼:然后呢?
小客服:她。。。。
小甲鱼:呃。。。你真牛逼!
小客服:那是,。。。
小甲鱼:下次有人想调戏你,我不阻止
小客服:滚!!
===========================================================================
小客服:小甲鱼,有个好评很好笑
小甲鱼:哦?
小客服:“有了小甲鱼,妈妈再也。。。。”
小甲鱼:哈哈哈,看到了,我还发了微博呢~
小客服:我看了你的微博呀!
小甲鱼:哟西~
小客服:那个回复“。。。。。。”
小甲鱼:T_T
============================================================================
小客服:小甲鱼,今天一个会员想找你
小甲鱼:哦?什么事儿?
小客服:他说你的一个学生月薪已经超过12k了
小甲鱼:哪里的?
小客服:上海的
小甲鱼:那正常,哪家公司的?
小客服:没说啊
小甲鱼:哦
小客服:老大,为什么我工资那么低啊,是时候涨工资了!!
小甲鱼:啊?你说什么?外面风大,听不见啊~~~~
小客服:滚!!!
代码我之前加过注释,也放这儿了,
#定义写入函数
def save_file(boy,girl,count): #传入两个列表(用于存储对话内容)和一个计数器
    file_name_boy='boy_'+str(count)+'.txt'#新建一系列文件,命名由字符串拼接
    file_name_girl='girl_'+str(count)+'.txt'#同理
   
    boy_file=open(file_name_boy,'w')#以写入方式打开
    girl_file=open(file_name_girl,'w') #同理
   
    boy_file.writelines(boy) #写入
    girl_file.writelines(girl)
   
    boy_file.close()   #关闭
    girl_file.close()
   
#定义切分函数   
def spilt_file(file_name): #传入文件名
      f = open(file_name,"r",encoding='UTF-8')
         #关键点,编码方式                   就这里换个编码形式
      boy=[]   
      girl=[]
      count=1   
            
      for each_line in f: #遍历原对话文件每一行
            if each_line[:6]!='======':#以分割线判断
                (role,line_spoken)=each_line.split(':',1)
                #以:为界,分成元组,进行1次操作
                if role =='小甲鱼': #根据名称(前三个字符)不同分别记入两个列表
                  boy.append(line_spoken)
                if role =='小客服':
                  girl.append(line_spoken)
                  #到这一步,所有对话均被存入两列表
            else:#不是分割线的情况下,写入
                save_file(boy,girl,count) #调用写入,写入后清空列表,等待下次添加对话内容
               
                boy=[]
                girl=[]
                count+=1   #count从2到3时跳出循环,所以文件里计数器count为3的那一对文件就缺少了
            
      save_file(boy,girl,count)#第三段内容(上方for循环漏掉一次写入)
      f.close()   
      
spilt_file('record.txt')

Peteryo01223 发表于 2021-1-19 08:42:33

本帖最后由 Peteryo01223 于 2021-1-19 09:14 编辑

昨非 发表于 2021-1-18 19:37
标点符号要求是英文的,记事本里不好检查的,楼主可以把这个复制过去再试试

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

感谢指点。
不过,我这里还是报错。
我已经把你的文字,另存为 f 盘下的 record.txt 文件,这里没有重复后缀出现了。然后copy 你的代码,运行后,报错结果如下。感觉是不是我的文件读取路径,有问题?
Traceback (most recent call last):
File "C:/Users/user/Desktop/20210119a.py", line 43, in <module>
    spilt_file('record.txt')
File "C:/Users/user/Desktop/20210119a.py", line 18, in spilt_file
    f = open(file_name,"r",encoding='UTF-8')
FileNotFoundError: No such file or directory: 'record.txt'

Peteryo01223 发表于 2021-1-19 08:43:59

jackz007 发表于 2021-1-18 18:22
文件 'record.txt' 中只能有两种行存在,一种由 6 个 '=' 开头的分隔行,另一种是正常的文本 ...

感谢指点。如您所说,把中文 :,换为英文: 后,确实程序不报错了。
不过,运行后,什么也没发生。新的文件,没出现。

昨非 发表于 2021-1-19 09:14:58

Peteryo01223 发表于 2021-1-19 08:43
感谢指点。如您所说,把中文 :,换为英文: 后,确实程序不报错了。
不过,运行后,什么也没发生。新的 ...

理论上新的文件将会出现在你record的目录位置下

昨非 发表于 2021-1-19 09:17:23

Peteryo01223 发表于 2021-1-19 08:42
感谢指点。
不过,我这里还是报错。
我已经把你的文字,另存为 f 盘下的 record.txt 文件,这里没有 ...

record位置写的不对,你的文件放在哪儿就这哪儿就好,我是放在.py的同目录下的,你要嫌麻烦大可放到一起去,然后我的代码就应该没问题了

Peteryo01223 发表于 2021-1-19 09:37:36

为了,由浅入深,我先回溯一下。
我先在此抄写,第29课视频(旧),FishC 讲解到9分50秒的程序。如下。
f = open('f://record.txt')

boy = []
girl = []
count = 1

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

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

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

      boy_file.close()
      girl_file.close()

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

f.close()

运行后,报错如下:
Traceback (most recent call last):
File "C:/Users/user/Desktop/20210119a.py", line 7, in <module>
    for each_line in f:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 4: illegal multibyte sequence

jackz007 发表于 2021-1-19 10:18:25

本帖最后由 jackz007 于 2021-1-19 10:34 编辑

Peteryo01223 发表于 2021-1-19 09:37
为了,由浅入深,我先回溯一下。
我先在此抄写,第29课视频(旧),FishC 讲解到9分50秒的程序。如下。

...

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

girl , boy , count = [] , [] , 1
fp = open('record.txt' , encoding = 'UTF-8')                      # 为了减少干扰,'record.txt' 与源代码文件放到相同目录内。
for each_line in fp:
    if each_line . strip():                                       # 过滤空文本行
      if each_line[:6] != '======':                           # 如果当前行是文本行
            if ':' in each_line:                                  # 判断当前行是否可分割
                (role , line_spoken) = each_line . split(':', 1)# 只对可分割行进行分割
                if role == '小甲鱼':
                  boy . append(line_spoken)
                if role == '小客服':
                  girl . append(line_spoken)
            else:
                print(each_line)                                  # 把无法分割的行显示出来
      else:
            save(girl , boy , count)
            count += 1
fp . close()                                                      # 循环结束必须关闭文件
save(girl , boy , count)                                           # 把列表中的信息写入文件

Peteryo01223 发表于 2021-1-19 10:24:29

jackz007 发表于 2021-1-18 17:55
文件编码问题

      这么改

这个方法,挺管用的,每次这么写,都不会报错。
f = open('f://record.txt', encoding = 'UTF-8')
不过,就是文件夹里,还是没有任何新文件产生出来。

Peteryo01223 发表于 2021-1-19 10:28:16

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

牛人!成功了!
(有几个girl拼写少了最后的字母 l,有个 open 重复写了两遍。但是瑕不掩瑜,你还是太强!)

Peteryo01223 发表于 2021-1-19 10:29:49

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

多谢高人指点。我又欠你一个最佳,我记着。
页: [1]
查看完整版本: 第29课:一个任务。视频中的例子