本章所用test.txt文件可以在( [Python 从入门到放弃] 6. 文件与异常(一))找到并自行创建

现在有个需求,对test.txt中的文本内容进行修改:

(1)将期间的‘:’改为‘ said:’

(2)将修改后的内容以覆盖的形式重新写入到该文件

1.步骤分析:

在( [Python 从入门到放弃] 6. 文件与异常(一))我们提到

在进行文件操作时,需要逐行处理,可以使用迭代器

因为test.txt的内容是:

Man:Is this the right room for an argument?
Other Man:I've told once.
Man:No you haven't!
Other Man:Yes I have.
Man:When?
Other Man:Just now.
Man:No you didn't
......
Other Man:Now let's get one thing quite clear:I most definitely told you!
Man:Oh no you did't!
Other Man:Oh yes I did!

因为几乎每一行都带有 ‘:’ 需要被处理

所以采用迭代器符合条件需要

现在来看初步代码

ver 1:

the_file=open('f://test.txt',encoding='utf-8')

for line in the_file:

    (role,spoken)=line.split(':')
    print(role,' said:',spoken)

执行结果:
Man  said: Is this the right room for an argument?
Traceback (most recent call last):    #抛出异常

Other Man  said: I've told once.
  File "C:/Users/L/PycharmProjects/untitled3/1.py", line 6, in <module>

Man  said: No you haven't!

Other Man  said: Yes I have.

    (role,spoken)=line.split(':')
Man  said: When?

ValueError: not enough values to unpack (expected 2, got 1)
Other Man  said: Just now.

Man  said: No you didn't

程序运行时抛出异常,表明出错

我们来分析一下为什么会抛出异常

先来对比一下结果处理后输出的字符串和原本的:

Man  said: No you didn't

'''
1.Man  said: No you didn't 这段以及之前的语句都成功处理
2.该字符串后面一行是 ’...........‘ 也就是在处理到这一行时出错
'''

在代码中:

(role,spoken)=line.split(':')的意思时,将字符串line进行分割分割的标记时split()里面的’:‘split()会在line中找出所有冒号,将其切割比如:
原本文件中这一行:Man : No you haven't!
当line读取到这一行时
split(':')会在Man : No you haven't!这个字符串里,从':'的地方开始’切割‘,分成两段
一段为:Man
另一端为:No you haven't!
所以
(role,spoken)=line.split(':')
的意思是:
将前一段赋值给role
后一段赋值给spoken
就这样一行行读下去
当读到文件中
'........'这一行时
由于里面没有':'冒号,split()不知道该从那里切割
所以抛出异常报错

如果当这一行没有’:‘时,说明没有人说话,因此不需要加 ’ said:‘也不需要使用split(),因此就不会报错

ver 2:

the_file=open('f://test.txt',encoding='utf-8')

for line in the_file:
    if not line.find(':')==-1:
        (role,spoken)=line.split(':')
        print(role,' said:',spoken)
    else:
        print(line)

执行结果:
Traceback (most recent call last):
  File "C:/Users/L/PycharmProjects/untitled3/1.py", line 5, in <module>
    (role,spoken)=line.split(':')
ValueError: too many values to unpack (expected 2)
Man  said: Is this the right room for an argument?

Other Man  said: I've told once.

Man  said: No you haven't!

Other Man  said: Yes I have.

Man  said: When?

Other Man  said: Just now.

Man  said: No you didn't

......

'''
1. '.........'终于能正常输出了 这说明在遇到没有冒号的语句时 不会执行split()
2. 使用了find()作为判断条件,先将字符串line调用find()查找冒号,如果冒号不存在,则跳过处理语句,如果冒号存在,则正常处理
3.find()用于查找字符串是否包含某字符,不包含则返回-1
4.虽然避免了split()因没有冒号而引发异常,当似乎又出现了新的异常

'''
新的异常:ValueError: too many values to unpack (expected 2)

我们读一下原文件中的数据:

文件剩余数据:
......
Other Man:Now let's get one thing quite clear:I most definitely told you!
Man:Oh no you did't!
Other Man:Oh yes I did!

除了'.........'已经能够正常执行处理之外,
其它行还没有执行
我们看一下它的下一行:
’ Other Man:Now let's get one thing quite clear:I most definitely told you! ‘
这一行里面包含了两个冒号
所以split(’:‘)会将其’切割‘成三段
而我们的赋值语句:
(role,spoken)=line.split(':')
只能将前两段赋值给两个变量
剩余一段没有变量与之匹配,一脸懵逼,无所适从,只能报错,抛出异常

到了这里,我们可以发现:处理文本信息时,由于文本信息的特殊性,它并不能按照理想的形式排列,

本文的代码中,以冒号为标记,可以将讲述人与其言语切割成两段,并进行处理

然而,并不代表每一行数据都只存在一个冒号

有时为0个,2个,或者3个等

在ver1中我们遇到了没有冒号的形式

在ver2中采用规避的方法,事先调用find()函数,企图将没有冒号的数据行跳过split()语句

现在,遇到了冒号>1的情况,因此抛出异常

处理方法:

让split()只处理头一个冒号,将字符串’分割‘成两段,其余不管有多少个,都忽略:

 (role,spoken)=line.split(':',1) # 这个额外的参数控制‘split()’如何分解 

ver 3:

the_file=open('f://test.txt',encoding='utf-8')

for line in the_file:
    if not line.find(':')==-1:
        (role,spoken)=line.split(':',1)
        print(role,' said:',spoken)
    else:
        print(line)
运行结果:  #   正常

Man  said: Is this the right room for an argument?

Other Man  said: I've told once.

Man  said: No you haven't!

Other Man  said: Yes I have.

Man  said: When?

Other Man  said: Just now.

Man  said: No you didn't

......

Other Man  said: Now let's get one thing quite clear:I most definitely told you!

Man  said: Oh no you did't!

Other Man  said: Oh yes I did!

本例中,由于数据的特殊性,导致频出异常

虽然每次根据具体情况修改代码,但是难以确保之后不会出现数据的其它特殊情况

而导致异常

因此,需要有一个良好的异常机制来预防和处理随时都有可能发送的异常

本章结合修改文本数据后重新写回文件之要求,重新修改代码,完整代码如下:

the_file=open('f://test.txt','r',encoding='utf-8')

text=""
for line in the_file:
    if not line.find(':')==-1:
        (role,spoken)=line.split(':',1)
        str=role+' said:'+spoken

    else:
        str=line
    str+='\n'
    text+=str

the_file.close()

the_file=open('f://test.txt','w',encoding='utf-8')
the_file.write(text)
the_file.close()

如果数据文件的格式发生改变,这个代码会有问题,相应地也需要改变条件

if语句使用的条件有点不好读,也不好理解

这个代码有点‘脆弱’....如果再出现另一个异常情况,它就会有问题

 

[Python 从入门到放弃] 6. 文件与异常(二)的更多相关文章

  1. [Python 从入门到放弃] 5. 文件与异常(一)

    1.文件操作: 文件操作包含读/写 从文件中读取数据 向文件写入数据 Python中内置了open()方法用于文件操作 (更多关于open()BIF介绍 阅读此篇) 基本模板: 1.获取文件对象 2. ...

  2. python入门学习:9.文件和异常

    python入门学习:9.文件和异常 关键点:文件.异常 9.1 从文件中读取数据9.2 写入文件9.3 异常9.4 存储数据 9.1 从文件中读取数据 9.1.1 读取整个文件  首先创建一个pi_ ...

  3. [Python 从入门到放弃] 1. 列表的基本操作

    ''' 列表 Create By 阅后即焚 On 2018.1.29 ''' 1. 列表的定义 列表看起来好像其它编程语言中的数组,但列表具备更加强大的功能,它是Python完备的集合对象,现在,你可 ...

  4. Python从入门到放弃系列(Django/Flask/爬虫)

    第一篇 Django从入门到放弃 第二篇 Flask 第二篇 爬虫

  5. python全栈开发从入门到放弃之文件处理

    一.文件处理流程 1.打开文件,得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 事例文件内容 [一棵开花的树] 如何让你遇见我 在我最美丽的时刻 为这 我已在佛前求了五百年 求 ...

  6. Python从入门到放弃

    计算机基础 01 计算机基础之编程 02 计算机组成原理 03 计算机操作系统 04 编程语言分类 Python解释器 05 Python和Python解释器 06 执行Python程序的两种方式 0 ...

  7. [Python 从入门到放弃] 3. BIF(内建函数)

    BIF (built-in functions) Python中提供了70多个内建函数,具备大量的现成功能. BIF不需要专门导入,可以直接使用,拿来就用 1.print() # 在屏幕上打印输出 如 ...

  8. python从入门到放弃之进程

    在理解进程之前我们先了解一下什么是进程的概念吧 以下就是我总结的一些基本的进程概念 进程就是正在运行的程序,它是操作系统中,资源分配的最小单位(通俗易懂点也就是电脑给程序分配的一定内存操作空间).资源 ...

  9. python从入门到放弃之Tensorflow(一)

    Tensorflow使用错误集锦: 错误1 : FutureWarning: Conversion of the second argument of issubdtype from ‘float’ ...

随机推荐

  1. RecyclerView怎么能没有ItemClickListener?加一个!

    RecyclerView可以用来代替ListView来展现大量的数据.Google在RecyclerView中提升了性能,和更多好用的API. 简单介绍RecyclerView 使用RecyclerV ...

  2. Forward团队-爬虫豆瓣top250项目-团队编程项目开发环境搭建过程

    本次结对编程和团队项目我都需要用python环境,所以环境的搭建是一样的.(本文部分内容引用自己博客:http://www.cnblogs.com/xingyunqi/p/7527411.html) ...

  3. Hadoop/Spark相关面试问题总结

    面试回来之后把其中比较重要的问题记了下来写了个总结: (答案在后面) 1.简答说一下hadoop的map-reduce编程模型 2.hadoop的TextInputFormat作用是什么,如何自定义实 ...

  4. Scala_基本语法

    基本语法 声明值和变量 Scala有两种类型的变量: val:是不可变的(变量的引用不可变),在声明时就必须被初始化,而且初始化以后就不能再赋值: var:声明的时候需要进行初始化,初始化以还可以再对 ...

  5. android TextView 设置部分文字背景色和文字颜色

    通过SpannableStringBuilder来实现,它就像html里边的元素改变指定文字的文字颜色或背景色 public class MainActivity extends Activity { ...

  6. 5.Django高级

    管理静态文件 项目中的CSS.图片.js都是静态文件 配置静态文件 在settings 文件中定义静态内容 STATIC_URL = '/static/' STATICFILES_DIRS = [ o ...

  7. 动态设置和访问cxgrid列的Properties

    动态设置和访问cxgrid列的Properties   设置: cxGrid1DBTableView1Column.PropertiesClass   =   TcxTextEditPropertie ...

  8. 1*1卷积核在GoogleLeNet中的作用

    1. 实现跨通道的交互和信息整合 1×1的卷积层(可能)引起人们的重视是在NIN的结构中,论文中林敏师兄的想法是利用MLP代替传统的线性卷积核,从而提高网络的表达能力.文中同时利用了跨通道poolin ...

  9. EFCore2.1中DbFirst和CodeFirst简单使用

    EFCore中没有DbFirst了吧,应该都是Code First 先说说第一种,Code First From Database(DbFirst)数据库先行,这种方式就要命令行了...(特不喜欢命令 ...

  10. CentOS 7 - 安装Oracle JDK8

    我们要在CentOS安装最新版本的JDK8,需要首先将JDK下载到服务器,然后通过操作系统自带的工具yum进行安装. 本文我们将介绍CentOS 7下JDK8的安装. 从官网下载页面找到JDK8的下载 ...