程序要有所作为,就需要与周遭世界通信。它需要与用户交互、读写文件、访问网页等。通常,我们称之为输入和输出。
除了基本的控制台I/O,还有文件I/O。
设置字符串格式
字符串插入
字符串插入是一种设置字符串格式的简单方法,是Python从编程语言C那里借鉴而来的。下面是如何控制小数位数的示例:
# 字符串插入
x = 1/81
print('x=%.2f'% x)
字符串插入表达式的格式:format % value,其中format是包含一个或多个%字符的字符串。在示例'x=%.2f'% x中,子串%.2f是一个格式设置命令,让Python获取后面提供的第一个值(x),并将其显示为包含两位小数的浮点数。
说明符 | 含义 |
---|---|
d | 整数 |
o | 八进制(基数为8的)值 |
x | 小写十六进制(基数为16的)数 |
X | 大写十六进制(基数为16的)数 |
e | 小写科学计数法表示的浮点数 |
E | 大写科学计数法表示的浮点数 |
F | 浮点数 |
s | 字符串 |
% | %字符 |
格式字符串
在Python中,另一种创建美观字符串的方式是结合使用格式字符串和字符串函数format(value,format_spec)。格式字符串中,用大括号括起的内容将被替换,这称为命名替换。命名替换可读性极佳,我们还可以按位置替换值。同时我们也可以像字符串插入那样使用转换说明符。还可以使用大括号设置格式参数。代码如下:
# 格式字符串
zoo = 'my {pet} is hahaha!'.format(pet='dog')
# 我们还可以换成采用位置替换的方式
zoo_1 = 'my {0} is {1}!'.format('dog','hahaha')
# 也可以像上面字符串插入那样使用转换说明符
num_1 = '1/81={x}'.format(x=1/81)
num_2 = '1/81={x:.2f}'.format(x=1/81)
# 可以使用大括号设置格式参数
num_3 = '1/81={x:.{d}f}'.format(x=1/81,d=3)
字符串插入和格式字符串的区别
相比字符串插入,格式字符串更灵活、更强大、但也更复杂。如果只想创建一些格式简单的字符串,字符串插入可能是最佳的选择;而格式字符串更适合庞大而复杂的设置任务,如创建网页或格式邮件。读写文件
文件可以分为文本文件和二进制文件。另外,要熟悉文件的绝对路径名称和相对路径名称。在Windows系统中,路径名是用反斜杠(\)分割的,而在Linux和Mac系统中,是用斜杠(/)分割的。
检查文件和文件夹
我们在下面的代码中列出检查文件和文件夹的函数,注释部分有其功能说明。
# 检查文件和文件夹。需要导入os
# 实用的文件和文件夹函数
os.getcwd() # 返回当前工作目录的名称,字符串类型
os.listdir(p) # 返回一个字符串列表,其中包含路径p指定的文件夹中所有文件和文件夹的名称
os.chdir(p) # 将当前工作目录设置为路径p
os.path.isfile(p) # 当路径p指定的是一个文件的名称时,返回True,否则返回False
os.path.isdir(p) # 当路径p指定的是一个文件夹的名称时,返回True,否则返回False
os.stat(fname) # 返回有关fname的信息,如大小(单位为字节)和最后一次修改时间
下面我们定义一个获得路径中所有py文件的函数。
# 下面是一个用来获取指定目录中所有py文件的函数
def list_py(path=None):
if path == None:
path = os.getcwd()
return [fname for fname in os.listdir(path) if os.path.isfile(fname) if fname.endswith('.py')]
处理文件
在Python中,处理文本文件相对容易。通常分为3步:打开文件、处理文件、关闭文件。
我们现在下表中列出Python文件打开模式:
字符 | 含义 |
---|---|
'r' | 为读取而打开文件(默认模式) |
'w' | 为写入而打开文件 |
'a' | 为在文件末尾附件而打开文件 |
'b' | 二进制模式 |
't' | 文本模式(默认模式) |
'+' | 为读写打开文件 |
逐行读取文本文件
读取文本文件的最常见方式就是每次读入一行。下面代码是在屏幕上打印文件内容:
# 处理文本文件
filename = os.getcwd()+'\\data.txt'
# 下面是一个逐行读取文本文件的函数
def print_files(filename):
f = open(filename,'r')
for line in f:
print(line,end='') # 把末尾设置为"",如果不这样设置,输出的内容将包含额外的空行
f.close()
将整个文本文件作为一个字符串进行读取
另一种读取文本文件的常见方式是将其作为一个大型字符串进行读取。代码如下:
# 将整个文本文件作为一个字符串进行读取
def print_files2(filename):
f = open(filename)
print(f.read())
f.close()
print_files2(filename)
# 上面的函数可以写成更简单的形式,更加紧凑,可读性相对较高
print(open(filename,'r').read())
比起逐行读入,这种方法更短小,简单,但是如果读取的文件很大时,将占用很大的内存,这可能降低计算机的运行速度,甚至导致计算机崩溃
写入文本文件
写入文本文件只比读取文本文件复杂一点点。例如下面这个函数是用来创建一个名为story.txt的文本文件:
# 写入文本文件
# 下面是一个写入文本文件的函数
def make_story1():
f = open('story.txt','w') # 如果story.txt已经存在,那么它将会被删除,所以应该先检查是否存在
f.write('Mary had a little lamb,\n')
f.write('and then she had some more.\n')
如果story.txt已经存在时,调用open('story.txt','w')会将它删除,如果我们不想覆盖story.txt,应该先检查它是否存在,我们把上面的函数改成下面的样式:
# 改进的写入文本文件函数
def make_story2():
if os.path.isfile('story.txt'):
print('story.txt already exists!')
else:
f = open('story.txt','w')
f.write('Mary had a little lamb,\n')
f.write('and then she had some more.\n')
附加到文本文件末尾
将字符串加入到文本文件时,一种常见的方式是将它们附加到文件末。与模式'w'不同,这种模式不会删除文件既有的内容。例如:
# 将内容附件到文本文件末尾,不删除文件既有的内容
def add_to_story(line,fname = 'story.txt'):
f = open(fname,'a') # 注意文件是以附加模式a打开的
f.write(line)
将字符串插入到文件开头
相比在文件末尾附加字符串,将字符串写入文件开头不那么容易。要将文本插入到文件开头,最简单的方式:将文件读取到一个字符串中,将新文本插入到该字符串,再将这个字符串写入原来的文件。如下所示:
# 将字符串插入到文件的开头
def insert_title(title,fname = 'story.txt'):
f = open(fname,'r+')
temp = f.read()
temp = title+'\n''\n'+temp
# 调用f.read()以后,文件指针指向文件末尾。
# 通过调用f.seek(0),让文件指针重新指向了文件开头,
# 这样写入f时,将从文件开头开始
f.seek(0) # 让文件指针指向文件开头。
f.write(temp)
处理二进制文件
如果文件不是文本文件,它就被视为二进制文件。二进制文件以模式'b'代开,而你可以访问各个字节。
下面定义一个函数来检查文件是否为GIF图像文件。
# 定义一个检查文件是不是GIF图像的函数,所有GIF图像都已(ox47,ox49,ox46,ox38)开头
def is_GIF(fname):
f = open(fname,'br')
first4 = tuple(f.read(4))
return first4 == (ox47,ox49,ox46,ox38)
访问二进制文件的各个字节是一种非常低级的操作,在处理二进制文件方面,pickle通常是一种方便得多的方式。
模块pickle:对象串行化。基本思想:将复杂的数据结构转换为字节流,即创建数据结构的串行化表示。
Python模块pickle让你能够轻松读写几乎任何数据结构。
import pickle
# 使用pickle.dump()将数据结构存储到磁盘,
# 再使用pickle.load()从磁盘获取数据结构
def make_pickle_file():
grades = {'alan':[4,8,10,10],
'tom':[7,7,7,8],
'dan':[5,None,7,7],
'may':[10,8,10,10]}
outfile = open('grade.txt','wb')
pickle.dump(grades,outfile)
def get_pickle_data():
infile = open('grade.txt','rb')
grades = pickle.load(infile)
return grades
除了pickle模块,Python还提供了shelve模块和splite3模块,可以通过阅读文档获取详细信息。
读取网页
Python提供了urllib模块来完成读取网页的任务。
# 读取网页
import urllib.request
response = urllib.request.urlopen('http://gitbook.cn/')
html = response.read()
除了模块urllib,还有webbrowser模块,大家可以通过官网文档获取详细信息。