文档测试
文件读写
操作文件和目录
Python实例
文档测试:Python内置的“文档测试”(doctest)模块可以直接提取注释中的代码并执行测试。doctest严格按照Python交互式命令行的输入和输出来判断测试结果是否正确。只有测试异常的时候,可以用...
表示中间一大段烦人的输出
class Dict(dict):
'''
Simple dict but also support access as x.y style.
>>> d1 = Dict()
>>> d1['x'] = 100
>>> d1.x
100
>>> d1.y = 200
>>> d1['y']
200
>>> d2 = Dict(a=1, b=2, c='3')
>>> d2.c
'3'
>>> d2['empty']
Traceback (most recent call last):
...
KeyError: 'empty'
>>> d2.empty
Traceback (most recent call last):
...
AttributeError: 'Dict' object has no attribute 'empty'
'''
def __init__(self, **kw):
super(Dict, self).__init__(**kw)
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
def __setattr__(self, key, value):
self[key] = value
if __name__=='__main__':
import doctest
doctest.testmod()
把__getattr__()
方法注释掉,再运行就会报错
class Dict(dict): ''' Simple dict but also support access as x.y style. >>> d1 = Dict() >>> d1['x'] = 100 >>> d1.x 100 >>> d1.y = 200 >>> d1['y'] 200 >>> d2 = Dict(a=1, b=2, c='3') >>> d2.c '3' >>> d2['empty'] Traceback (most recent call last): ... KeyError: 'empty' >>> d2.empty Traceback (most recent call last): ... AttributeError: 'Dict' object has no attribute 'empty' ''' def __init__(self, **kw): super(Dict, self).__init__(**kw) #def __getattr__(self, key): # try: # return self[key] # except KeyError: # raise AttributeError(r"'Dict' object has no attribute '%s'" % key) def __setattr__(self, key, value): self[key] = value if __name__=='__main__': import doctest doctest.testmod()
注意到最后两行代码。当模块正常导入时,doctest不会被执行。只有在命令行运行时,才执行doctest。所以,不必担心doctest会在非测试环境下执行。
文件读写:
读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)
调用read()
会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)
方法,每次最多读取size个字节的内容。另外,调用readline()
可以每次读取一行内容,调用readlines()
一次读取所有内容并按行返回list
如果文件很小,read()
一次性读取最方便;如果不能确定文件大小,反复调用read(size)
比较保险;如果是配置文件,调用readlines()
最方便
像open()
函数返回的这种有个read()
方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object不要求从特定类继承,只要写个read()
方法就行。
StringIO
就是在内存中创建的file-like Object,常用作临时缓冲。
f1=open('D:\python_workspace\\test1.txt','r') print f1.read()
读文件:
with open('D:\python_workspace\\test1.txt', 'r') as f1: #Python引入了with语句来自动帮我们调用close()方法,并且有try...finally功能 for line in f1.readlines(): print(line.strip())
二进制文件:
前面讲的默认都是读取文本文件,并且是ASCII编码的文本文件。要读取二进制文件,比如图片、视频等等,用'rb'
模式打开文件即可
字符编码:
要读取非ASCII编码的文本文件,就必须以二进制模式打开,再解码。比如GBK编码的文件:
>>>f = open(
'/Users/michael/gbk.txt',
'rb')
>>>u = f.read().decode(
'gbk')
>>> u
u'\u6d4b\u8bd5'
>>> print u
测试
import codecs
withcodecs.open(
'/Users/michael/gbk.txt',
'r',
'gbk')
asf:
f.read()
# u'\u6d4b\u8bd5'
写文件:
with open('D:\python_workspace\\test2.txt', 'w') as fw: fw.write('Hello, world!') with open('D:\python_workspace\\test2.txt', 'r') as fr: print fr.read()
操作文件和目录:
import os
print os.environ
print os.name
print os.getenv('PATH')#得到path的环境变量
print os.path.abspath('.')#查看当前目录的绝对路径
print os.path.join('C:\Python27\\tornado\demos\\tornado-test','testdir')#显示出新目录的完整路径
print os.makedirs('C:\Python27\\tornado\demos\\tornado-test\\testdir')#创建一个目录
#print os.rmdir('C:\Python27\\tornado\demos\\tornado-test\\testdir')#删掉一个目录
把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()
函数,这样可以正确处理不同操作系统的路径分隔符:
在Linux/Unix/Mac下,os.path.join()
返回这样的字符串:part-1/part-2
而Windows下会返回这样的字符串: part-1\part-2
同样的道理,要拆分路径时,也不要直接去拆字符串,而要通过os.path.split()
函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名:
print os.path.split('/Users/michael/testdir/file.txt')
print os.path.splitext('/path/to/file.txt') #os.path.splitext()可以直接让你得到文件扩展名, 这些合并、拆分路径的函数并不要求目录和文件要真实存在,它们只对字符串进行操作。
shutil
模块提供了copyfile()
的函数
编写一个search(s)
的函数,能在当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出完整路径:
# -*- coding: UTF-8 -*-
import os, sys
def search(name, path='.'):
found = []
for f in [os.path.abspath(os.path.join(path, x)) for x in os.listdir(path)]:
if os.path.isfile(f) and os.path.split(f)[1].find(name) != -1:
found.append(f)
for path in [x for x in os.listdir(path) if os.path.isdir(x)]:
found.extend(search(name, path))
return found
l = search('hello.py')
print l
Python实例:
一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
#!/usr/bin/python
# -*- coding: UTF-8 -*-
tour = []
height = []
hei = 100.0 # 起始高度
tim = 10 # 次数
for i in range(1, tim + 1):
# 从第二次开始,落地时的距离应该是反弹高度乘以2(弹到最高点再落下)
if i == 1:
tour.append(hei)
else:
tour.append(2 * hei)
hei /= 2
height.append(hei)
print('总高度:tour = {0}'.format(sum(tour)))
print('第10次反弹高度:height = {0}'.format(height[-1]))
两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
for i in range(ord('x'), ord('z') + 1):
for j in range(ord('x'), ord('z') + 1):
if i != j:
for k in range(ord('x'), ord('z') + 1):
if (i != k) and (j != k):
if (i != ord('x')) and (k != ord('x')) and (k != ord('z')):
print 'order is a -- %s\t b -- %s\tc--%s' % (chr(i), chr(j), chr(k))
- 打印出如下图案(菱形):
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from sys import stdout
for i in range(4):
for j in range(2 - i + 1):
stdout.write(' ')
for k in range(2 * i + 1):
stdout.write('*')
print
for i in range(3):
for j in range(i + 1):
stdout.write(' ')
for k in range(4 - 2 * i + 1):
stdout.write('*')
print
有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
a = 2.0
b = 1.0
s = 0
for n in range(1, 21):
s += a / b
t = a
a = a + b
b = t
print s
求1+2!+3!+...+20!的和。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
n = 0
s = 0
t = 1
for n in range(1,21):
t *= n
s += t
print '1! + 2! + 3! + ... + 20! = %d' % s
利用递归方法求5!。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
def fact(j):
sum = 0
if j == 0:
sum = 1
else:
sum = j * fact(j - 1)
return sum
for i in range(5):
print '%d! = %d' % (i, fact(i))
利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来。
# -*- coding: UTF-8 -*-
def output(s, l):
if l == 0:
return
print (s[l - 1]),
output(s, l - 1)
s = raw_input('Input a string:')
l = len(s)
output(s, l)