杨桃的Python进阶讲座5——输入和读文件

本人CSDN博客专栏:https://blog.csdn.net/yty_7

Github地址:https://github.com/yot777/

上次说到等号和赋值号。为啥要强调赋值顺序是从右到左呢?因为我们中国人从小说的汉语,是一种标准的从左到右,从大到小的语言结构即SVO(Subject Verb Object)结构即主谓宾结构,这样我们就不容易理解从右到左的顺序,但实际上,从右到左的用法在世界上很多语言都有,比如英语写信的地址是怎么写的,大家还记得吗?

中国北京市朝阳区华威南路A小区2单元888号 -->

Room.888,Unit 2,Community A,South Huawei Rd.,Chaoyang District,Beijing,P.R.China.

这就是从小到大的书写方式,需要从右往左阅读。

除此之外日语、韩语的结构是SOV(Subject Object Verb)即主宾谓,就更需要从右往左阅读了。

所以,请大家一定记得赋值号是从右到左。

5.1 Python输入:

Python的输入很简单,使用input()函数就行。需要注意的有两点:

1. input()函数没有参数,但可以加入字符串作为输入的提示符。

2. 不管从键盘输入的什么,Python都认为是字符串类型,所以有些情况下需要转数据类型。

Python单行输入举例:

#直接将input()函数输入的内容赋值给变量t
>>> t = input("Please input:")   
Please input:6
>>> t
'6'    #注意变量t现在是字符'6'不是数字6
>>> s = t + 7
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not int   #报错,字符'6'无法直接和数字7相加
>>>
#将input()函数输入的内容转型为int(整型)之后再赋值给变量t
>>> t = int(input("Please input:"))  
Please input:6
>>> t
6     #变量t现在是数字6
>>> s = t + 7   #可以正常执行整数的加法
>>> print(s)
13

单行输入有很多无法克服的问题,比如无法输入换行的内容(就算加上\n也不行),也无法输入多个元素的列表,举例如下:

>>> t = input("Please input:")
Please input:[0,1,2]   #尝试输入一个[0,1,2]列表
>>> t
'[0,1,2]'     #被解析为了'[0,1,2]'字符串
>>> t[0]
'['           #'[0,1,2]'字符串的第1个元素是'[' 
>>> t[1]
'0'           #'[0,1,2]'字符串的第2个元素是'0' 
>>> t[2]
','           #'[0,1,2]'字符串的第3个元素是',' 
>>> t = list(input("Please input:"))  #即使被强制转型为list类型也不行
Please input:[0,1,2]   
>>> t[0]
'['
>>> t[1]
'0'
>>> t[2]
','
>>> t = input("input:")
input:a\nb\nc      #原本是想用\n作为换行符输出3行
>>> t
'a\\nb\\nc'

5.2 Python读文件:

既然input()函数不支持多行输入,我们可以使用一个变通的方法来解决这个问题:读文件!

读文件分为以下几步:

1. 打开文件,使用open()函数进行,完整的函数是:

f = open('test.txt', 'r')

open函数的第一个参数是文件名,第二个参数表示文件类型:r表示文本文件,rb表示二进制文件

第二个参数可省略,默认是文本文件

open函数的返回值是一个文件对象。注意,是一个实例化对象!这意味着它可以有自己的方法。

2. 读取文件,使用read()或者readline()方法,他们的区别是:

read() 读取整个文件,它通常用于将整个文件内容放到一个字符串变量中;

readline() 只读取一行,然后把该行放到一个放到一个字符串变量中;

readlines() 读取整个文件,自动将文件内容分解成一个包含所有行的列表。

实际应用中,readlines比read和readlines用得更广泛,自动将文件内容分解成一个包含所有行的列表更利于后续处理。

lines = f.readlines()

3. 读取完成后,使用close()方法关闭文件,避免文件对象一直被占用不释放内存。

f.close()

我们试验一个例子,假如有如下的test.txt文件:

#test.txt文件
1	2	3	4	5
6	7	8	9	10
11	12	13	14	15
16	17	18	19	20

每行5个元素,元素之间用Tab键分隔,一共有4行,我们直接使用readlines()方法:

#读取文件试验1
#打开原始文件
>>> f = open('test.txt')
#readlines() 读取整个文件,自动将文件内容分析成一个包含所有行的列表
>>> lines = f.readlines()
>>> lines
['1\t2\t3\t4\t5\n', '6\t7\t8\t9\t10\n', '11\t12\t13\t14\t15\n', '16\t17\t18\t19\t20']
#关闭文件
>>> f.close()

这样把全部行都读取出来了,但并不是我们想要的结果,因为还没去掉元素之间用Tab分隔符,行尾的回车换行符也没去掉。

下面分三步走:

先把每一行都读取出来

#定义一个空列表lineArr 
lineArr = []
#打开源文件test.txt
f = open('test.txt')
#readlines() 读取整个文件,自动将文件内容分析成一个包含所有行的列表lines
lines = f.readlines()
#遍历lines的每一行line
for line in lines:
    #将当前行的内容添加到列表lineArr 
    lineArr.append(line)
    #打印出当前的lineArr列表
    print("lineArr:", lineArr)
#打印出最终的lineArr列表
print("最终的lineArr:",lineArr)
#关闭文件
f.close()

运行结果:
lineArr: ['1\t2\t3\t4\t5\n']
lineArr: ['1\t2\t3\t4\t5\n', '6\t7\t8\t9\t10\n']
lineArr: ['1\t2\t3\t4\t5\n', '6\t7\t8\t9\t10\n', '11\t12\t13\t14\t15\n']
lineArr: ['1\t2\t3\t4\t5\n', '6\t7\t8\t9\t10\n', '11\t12\t13\t14\t15\n', '16\t17\t18\t19\t20']
最终的lineArr: ['1\t2\t3\t4\t5\n', '6\t7\t8\t9\t10\n', '11\t12\t13\t14\t15\n', '16\t17\t18\t19\t20']

然后将每一行先去掉回车,再以Tab符作为元素之间的分隔符号
 

#定义一个空列表lineArr 
lineArr = []
#打开源文件test.txt
f = open('test.txt')
#readlines() 读取整个文件,自动将文件内容分析成一个包含所有行的列表lines
lines = f.readlines()
#遍历lines的每一行line
for line in lines:
    #将每一行先去掉回车,再以Tab符作为元素之间的分隔符号
    linenew = line.strip().split('\t')
    #将当前行的内容添加到列表lineArr 
    lineArr.append(linenew)
    #打印出当前的lineArr列表
    print("lineArr:", lineArr)
#打印出最终的lineArr列表
print("最终的lineArr:",lineArr)
#关闭文件
f.close()

运行结果:
lineArr: [['1', '2', '3', '4', '5']]
lineArr: [['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10']]
lineArr: [['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10'], ['11', '12', '13', '14', '15']]
lineArr: [['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10'], ['11', '12', '13', '14', '15'], ['16', '17', '18', '19', '20']]
最终的lineArr: [['1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10'], ['11', '12', '13', '14', '15'], ['16', '17', '18', '19', '20']]

最后将每个字符数字转型为整型数字

#定义一个空列表lineArr 
lineArr = []
#打开源文件test.txt
f = open('test.txt')
#readlines() 读取整个文件,自动将文件内容分析成一个包含所有行的列表lines
lines = f.readlines()
#遍历lines的每一行line
for line in lines:
    #将每一行先去掉回车,再以Tab符作为元素之间的分隔符号
    linenew = line.strip().split('\t')
    #len(linenew)是linenew列表长度,也就是linenew列表的元素个数
    #for in in range(m)表示i从0增加到m-1
    for i in range(len(linenew)):
    	#从linenew[0]到linenew[m-1]的每个元素都转为整型数字
    	linenew[i] = int(linenew[i])
    #将当前行的内容添加到列表lineArr 
    lineArr.append(linenew)
    #打印出当前的lineArr列表
    print("lineArr:", lineArr)
#打印出最终的lineArr列表
print("最终的lineArr:",lineArr)
#关闭文件
f.close()

运行结果:
lineArr: [[1, 2, 3, 4, 5]]
lineArr: [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
lineArr: [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]
lineArr: [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]
最终的lineArr: [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]

这样就完成了原始文件的数据处理。关于循环和遍历在后面还会以再讲。

由于文件读写时都有可能产生IOError(找不到文件等等意外情况),一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来实现:

try:
    f = open('test.txt', 'r')
    print(f.read())
finally:
    if f:
        f.close()

但是每次都这么写实在太繁琐,所以,Python引入了with语句来自动帮我们自动调用close()方法:

with open('test.txt', 'r') as f:
    print(f.read())

这样就不用担心文件没有被关闭了。

总结:

Python的单行输入用input()函数,但无论输入什么,Python都认为是字符串类型。

Python的文件读写有三个步骤:打开、读取、关闭。读取又有三种方法:read、readline、readlines。可以使用with语句省略关闭文件的步骤。

本人CSDN博客专栏:https://blog.csdn.net/yty_7

Github地址:https://github.com/yot777/

如果您觉得本篇本章对您有所帮助,欢迎关注、评论、点赞!Github欢迎您的Follow、Star!

发布了55 篇原创文章 · 获赞 16 · 访问量 6111

猜你喜欢

转载自blog.csdn.net/yty_7/article/details/104335684
今日推荐