一个程序可以从键盘读取输入,也可以从文件读取输入;而程序的结果可以输出到屏幕上,也可以保存到文件中便于以后使用。本文介绍Python中最基本的I/O函数。
一、控制台I/O
读取键盘输入
内置函数
input([prompt])
,用于从标准输入读取一个行,并返回一个字符串(去掉结尾的换行符):
1
s = input("Enter your input:" )
注:在Python 3.x版本中取消了 raw_input() 函数。
打印到屏幕
最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式:
1
print([object, ... ][, sep=' ' ][, end='endline_character_here' ][, file=redirect_to_here ])
方括号内是可选的,sep表示分割符,end表示结束符,file表示重定向文件。如果要给sep、end、file指定值必须使用关键字参数。
1 2
print ('hello' , 'world' , sep='%' ) print ('hello' , 'world' , end='*' )
二、文件I/O
读写文件之前,先用open()函数打开一个文件,它会返回一个文件对象(file object):
1
f = open (filename,mode)
如果不指定mode参数,文件将默认以
‘r’
模式打开。模式中的字符有:
r
:只读
w
:只写,如果文件已存在则将其覆盖。如果该文件不存在,创建新文件
+
:读写(
不能单独使用
)
a
:打开文件用于追加,只写,不存在则创建新文件
b
:以二进制模式打开(
不能单独使用
)
所以可能的模式大概有
r、w、r+、w+、rb、wb、rb+、wb+、a、a+、ab、ab+
,注意只有w和a可以创建文件。
通常情况下,文件都是以文本模式(text mode)打开的,也就是说,从文件中读写的是以一种特定的编码格式进行编码(默认的是 UTF-8)的
字符串
。如果文件以二进制模式(binary mode)打开,数据将以
字节对象
的形式进行读写:
1 2 3
f = open ('a.txt' ,'wb+' ) f.write ('I like apple!' ) f.write (b'I like apple!' )
Bytes对象
是0到127的不可修改的整数序列,或纯粹的 ASCII 字符,它的用途是存储二进制数据。
可以通过
在一个字符串前面加上’b’
来创建一个bytes literal;
也可以通过
bytes() 函数
创建一个 bytes 对象。
注意:如果bytes() 函数的初始化器是一个字符串,那么必须提供一种编码。
1 2
b1 = b'This is string ' b2 = bytes('This is string ', 'UTF -8 ') # 必须指定编码格式
字符串对象与字节对象是不兼容的,要将 bytes 转变为 str, bytes 对象必须要进行解码,使用
decode()
方法:
1 2 3 4 5
b = bytes('This is string' , 'UTF-8' ) print(b, b.decode(), sep='\n' ) # 输出: # b'This is string' # This is string
文件对象的方法
(假设f是一个文件对象):
f.read(size) :
读取size个字节的数据,然后作为字符串或 bytes 对象返回。size是一个可选参数,如果不指定size,则读取文件的所有内容。
f.readline() :
读取一行。在字符串末尾会留下换行符 (\n),如果到文件尾,返回空字符串。
f.readlines() :
读取所有行,储存在列表中,每个元素是一行,相当于
list(f)
。
f.write(string) :
将 string 写入到文件中,返回写入的字符数。如果以二进制模式写文件,需要将string转换为 bytes 对象。
f.tell() :
返回文件对象当前所处的位置,它是从文件开头开始算起的字节数。
f.seek(offset, from_what) :
改变文件对象所处的位置。offset是相对参考位置的偏移量,from_what 取值 0(文件头, 默认)、1(当前位置)、2(文件尾)表示参考位置。
f.close() :
关闭文件对象。
这些都是很常用的方法,当然文件对象不止这些方法。根据打开的模式不同,open() 返回的文件对象类型也不同:
TextIOWrapper
:文本模式,返回TextIOWrapper对象。
BufferedReader
:读二进制,即rb,返回BufferedReader对象。
BufferedWriter
:写和追加二进制,即wb、ab,返回BufferedWriter对象。
BufferedRandom
:读/写模式,即含有+的模式,返回BufferedRandom对象。
可以在这些文件对象上运行 dir() 或 help(),查看它们所有的方法。
1、在文本模式下,seek()方法只会相对于文件起始位置进行定位。(除了定位文件尾可以用
seek(0, 2)
之外)
2、可以循环迭代一个文件对象一行一行读取:
1 2
for line in f:print(line , end ='')
三、格式化输出
一般来说,我们希望更多的控制输出格式,而不是简单的以空格分割。这里有两种方式:
第一种是由你自己控制。使用字符串切片、连接操作以及
string
包含的一些有用的操作。
第二种是使用
str.format()
方法。
下面给一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# 第一种方式:自己控制 for x in range(1 , 11 ): print(str(x).rjust(2 ), str(x*x).rjust(3 ), end=' ' ) print(str(x*x*x).rjust(4 )) # 第二种方式:str.format() for x in range(1 , 11 ): print('{0:2d} {1:3d} {2:4d}' .format(x, x*x, x*x*x)) # 输出都是: # 1 1 1 # 2 4 8 # 3 9 27 # 4 16 64 # 5 25 125 # 6 36 216 # 7 49 343 # 8 64 512 # 9 81 729 # 10 100 1000
第一种方式中,字符串对象的
str.rjust()
方法的作用是将字符串靠右,并默认在左边填充空格,类似的方法还有
str.ljust()
和
str.center()
。这些方法并不会写任何东西,它们仅仅返回新的字符串,如果输入很长,它们并不会截断字符串。
我们注意到,
同样是输出一个平方与立方表,使用str.format()会方便很多。
str.format()的基本用法如下:
1 2
>>> print('We are the {} who say "{}!" '.format('knights ', 'Ni ') ) We are the knights who say "Ni!"
括号及括号里的字符将会被 format() 中的参数替换.。括号中的数字用于指定传入对象的位置:
1 2 3 4
>> > print('{0} and {1}' .format('Kobe' , 'James' ))Kobe and James >> > print('{1} and {0}' .format('Kobe' , 'James' ))James and Kobe
如果在 format() 中使用了
关键字参数
,那么它们的值会指向使用该名字的参数:
1 2
>>> print('The {thing} is {adj}.' .format(thing='flower' , adj='beautiful' ))The flower is beautiful.
可选项
':'
和格式标识符可以跟着 field name,这样可以进行更好的格式化:
1 2 3
>>> import math >>> print('The value of PI is {0:.3f}.' .format (math.pi )) The value of PI is 3.142 .
在
':'
后传入一个整数,可以保证该域至少有这么多的宽度,用于美化表格时很有用:
1 2 3 4 5 6 7
>>> table = {'Jack' :4127 , 'Rose' :4098 , 'Peter' :7678 }>>> for name, phone in table.items():... print('{0:10} ==> {1:10d}' .format(name, phone))... Peter ==> 7678 Rose ==> 4098 Jack ==> 4127
我们还可以将
参数解包
进行格式化输出。例如,将table解包为关键字参数:
1 2 3
table = {'Jack' :4127 , 'Rose' :4098 , 'Peter' :7678 } print ('Jack is {Jack}, Rose is {Rose}, Peter is {Peter}.' .format(**table))# 输出:Jack is 4127 , Rose is 4098 , Peter is 7678.
% 操作符也可以实现字符串格式化。它将左边的参数作为类似 sprintf() 式的格式化字符串,而将右边的代入:
1 2 3
import math print('The value of PI is %10.3 f.' %math.pi) # 输出:The value of PI is 3.142 .
因为这种旧式的格式化最终会从Python语言中移除,应该更多的使用 str.format() 。
附:文本模式与二进制模式
1、在Windows系统中,文本模式下,默认是将Windows平台的行末标识符 \r\n 在读时转为 \n ,而在写时将 \n 转为 \r\n 。 这种隐藏的行为对于文本文件是没有问题的,但是对于二进制数据像 JPEG 或 EXE 是会出问题的。在使用这些文件时请小心使用二进制模式。
2、在类Unix/Linux系统中,行末标识符为 \n,即文件以 \n 代表换行。所以Unix/Linux系统中在文本模式和二进制模式下并无区别。