CSDN下载:https://download.csdn.net/download/weixin_42859280/11254583
百度云:链接:https://pan.baidu.com/s/1iLe8CQ_Io9HOzM06x59IDw提取码:bt08
点击跳转Python 程序设计(第二版)董付国_清华大学出版社_习题答案与分析【针对8.4及其之前的】
Python 程序设计基础
习题答案与分析
第 1 章 基础知识
1.1 简单说明如何选择正确的 Python 版本。
答:
在选择 Python 的时候,一定要先考虑清楚自己学习 Python 的目的是什么,打算做哪方面的开发,有哪些扩展库可用,这些扩展库最高支持哪个版本的 Python ,是 Python 2.x 还是 Python 3.x ,最高支持到 Python 2.7.6 还是 Python 2.7.9 。这些问题都确定以后,再做出自己的选择,这样才能事半功倍,而不至于把大量时间浪费在 Python 的反复安装和卸载上。同时还应该注意,当更新的 Python 版本推出之后,不要急于更新,而是应该等确定自己所必须使用的扩展库也推出了较新版本之后再进行更新。
尽管如此, Python 3 毕竟是大势所趋,如果您暂时还没想到要做什么行业领域的应用开发,或者仅仅是为了尝试一种新的、好玩的语言,那么请毫不犹豫地选择 Python 3.x 系列的最高版本(目前是 Python 3.4.3 )。
1.2 为什么说 Python 采用的是基于值的内存管理模式?
Python 采用的是基于值的内存管理方式,如果为不同变量赋值相同值,则在内存中只有一份该值,多个变量指向同一块内存地址,例如下面的代码。
>>> x = 3
>>> id(x)
10417624
>>> y = 3
>>> id(y)
10417624
>>> y = 5
>>> id(y)
10417600
>>> id(x)
10417624
>>> x = [1, 2, 3, 1, 1, 2]
>>> id(x[0])==id(x[3])==id(x[4])
True
1.3 解释 Python 中的运算符 “ / ” 和 “ // ” 的区别。
答:
在 Python 2.x 中,“ / ”为普通除法,当两个数值对象进行除法运算时,最终结果的精度与操作数中精度最高的一致;在 Python 3.x 中,“ / ”为真除法,与除法的数学含义一致。
在 Python 2.x 和 Python 3.x 中,“ // ”表示整除,对整数或浮点数进行该运算时,结果为数学除法的整数部分。
1.4 在 Python 中导入模块中的对象有哪几种方式?
答:常用的有三种方式,分别为
● import 模块名 [as 别名 ]
● from 模块名 import 对象名 [ as 别名 ]
● from math import *
1.5 pip 是目前比较常用的 Python 扩展库管理工具。
1.6 解释 Python 脚本程序的“ __name__ ”变量及其作用。
答:
每个 Python 脚本在运行时都有一个“ __name__ ”属性。如果脚本作为模块被导入,则其“ __name__ ”属性的值被自动设置为模块名;如果脚本独立运行,则其“ __name__ ”属性值被自动设置为“ __main__ ”。利用“ __name__ ”属性即可控制 Python 程序的运行方式。
1.7 运算符“ % ” 可以 (可以、不可以)对浮点数进行求余数操作。
1.8 一个数字“ 5 ” 是 (是、不是)合法的 Python 表达式。
1.9 在 Python 2.x 中, input() 函数接收到的数据类型由 界定符 确定,而在 Python 3.x 中该函数则认为接收到的用户输入数据一律为 字符串 。
1.10 编写程序,用户输入一个三位以上的整数,输出其百位以上的数字。例如用户输入 1234 ,则程序输出 12 。(提示:使用整除运算。)
答:
1 ) Python 3.4.2 代码:
x = input('Please input an integer of more than 3 digits:')
try:
x = int(x)
x = x//100
if x == 0:
print('You must input an integer of more than 3 digits.')
else:
print(x)
except BaseException:
print('You must input an integer.')
2 ) Python 2.7.8 代码:
import types
x = input('Please input an integer of more than 3 digits:')
if type(x) != types.IntType:
print 'You must input an integer.'
elif len(str(x)) != 4:
print 'You must input an integer of more than 3 digits.'
else:
print x//100
第 2 章 Python 序列
2.1 为什么应尽量从列表的尾部进行元素的增加与删除操作?
答:
当列表增加或删除元素时,列表对象自动进行内存扩展或收缩,从而保证元素之间没有缝隙,但这涉及到列表元素的移动,效率较低,应尽量从列表尾部进行元素的增加与删除操作以提高处理速度。
2.2 range() 函数在 Python 2.x 中返回一个 包含整数的列表 ,而 Python 3.x 的 range() 函数返回一个 可迭代的 range 对象 。
2.3 编写程序,生成包含 1000 个 0 到 100 之间的随机整数,并统计每个元素的出现次数。
答:可以使用集合来实现该功能。
1 ) Python 3.4.2 代码
import random
x = [random.randint(0,100) for i in range(1000)]
d = set(x)
for v in d:
print(v, ':', x.count(v))
2 ) Python 2.7.8 代码
import random
x = [random.randint(0,100) for i in range(1000)]
d = set(x)
for v in d:
print v, ':', x.count(v)
也可以直接使用字典来实现该功能,并且获得更高的执行效率,例如下面的 Python 3.4.2 代码:
listRandom = [random.randint(1,100) for i in range(1000000)]
d = dict()
start = time.time()
for i in listRandom: # 对随机数列表扫描一次,即可得到结果
d[i] = d.get(i,0)+1
print(time.time()-start)
2.4 表达式“ [3] in [1, 2, 3, 4] ”的值为 False 。
2.5 编写程序,用户输入一个列表和 2 个整数作为下标,然后输出列表中介于 2 个下标之间的元素组成的子列表。例如用户输入 [1, 2, 3, 4, 5, 6] 和 2,5 ,程序输出 [3, 4, 5, 6] 。
答:
1 ) Python 3.4.2 代码
x = input('Please input a list:')
x = eval(x)
start, end = eval(input('Please input the start position and the end position:'))
print(x[start:end])
2 ) Python 2.7.8 代码
x = input('Please input a list:')
start, end = input('Please input the start position and the end position:')
print x[start:end]
2.6 列表对象的 sort() 方法用来对列表元素进行原地排序,该函数返回值为 None 。
2.7 列表对象的 remove() 方法删除首次出现的指定元素,如果列表中不存在要删除的元素,则抛出异常。
2.8 假设列表对象 aList 的值为 [3, 4, 5, 6, 7, 9, 11, 13, 15, 17] ,那么切片 aList[3:7] 得到的值是 [6, 7, 9, 11] 。
2.9 设计一个字典,并编写程序,用户输入内容作为“键”,然后输出字典中对应的“值”,如果用户输入的“键”不存在,则输出“您输入的键不存在!”
答:
1 ) Python 3.4.2 代码
d = {1:'a', 2:'b', 3:'c', 4:'d'}
v = input('Please input a key:')
v = eval(v)
print(d.get(v,' 您输入的的键不存在 '))
2 ) Python 2.7.8 代码
d = {1:'a', 2:'b', 3:'c', 4:'d'}
v = input('Please input a key:')
print(d.get(v,' 您输入的的键不存在 '))
2.10 编写程序,生成包含 20 个随机数的列表,然后将前 10 个元素升序排列,后 10 个元素降序排列,并输出结果。
答:
1 ) Python 3.4.2 代码
import random
x = [random.randint(0,100) for i in range(20)]
print(x)
y = x[0:10]
y.sort()
x[0:10] = y
y = x[10:20]
y.sort(reverse=True)
x[10:20] = y
print(x)
2 ) Python 2.7.8 代码
import random
x = [random.randint(0,100) for i in range(20)]
print x
y = x[0:10]
y.sort()
x[0:10] = y
y = x[10:20]
y.sort(reverse=True)
x[10:20] = y
print x
2.11 在 Python 中,字典和集合都是用一对 大括号 作为界定符,字典的每个元素有两部分组成,即 “键” 和 “值” ,其中 “键” 不允许重复。
2.12 使用字典对象的 items() 方法可以返回字典的“键 - 值对”列表,使用字典对象的 keys() 方法可以返回字典的“键”列表,使用字典对象的 values() 方法可以返回字典的“值”列表。
2.13 假设有列表 a = ['name', 'age', 'sex'] 和 b = ['Dong', 38, 'Male'] ,请使用一个语句将这两个列表的内容转换为字典,并且以列表 a 中的元素为“键”,以列表 b 中的元素为“值”,这个语句可以写为 c = dict(zip(a,b)) 。
2.14 假设有一个列表 a ,现要求从列表 a 中每 3 个元素取 1 个,并且将取到的元素组成新的列表 b ,可以使用语句 b = a[::3] 。
2.15 使用列表推导式生成包含 10 个数字 5 的列表,语句可以写为 [5 for i in range(10)] 。
2.16 不可以 (可以、不可以)使用 del 命令来删除元组中的部分元素。
第 3 章 选择与循环
3.1 分析逻辑运算符“ or ”的短路求值特性。
答:
假设有表达式“表达式 1 or 表达式 2 ”,如果表达式 1 的值等价于 True ,那么无论表达式 2 的值是什么,整个表达式的值总是等价于 True 。因此,不需要再计算表达式 2 的值。
3.2 编写程序,运行后用户输入 4 位整数作为年份,判断其是否为闰年。如果年份能被 400 整除,则为闰年;如果年份能被 4 整除但不能被 100 整除也为闰年。
答:
1 ) Python 3.4.2 代码
x = input('Please input an integer of 4 digits meaning the year:')
x = eval(x)
if x%400==0 or (x%4==0 and not x%100==0):
print('Yes')
else:
print('No')
2 ) Python 2.7.8 代码
x = input('Please input an integer of 4 digits meaning the year:')
if x%400==0 or (x%4==0 and not x%100==0):
print 'Yes'
else:
print 'No'
3.3 Python 提供了两种基本的循环结构: for 循环 和 while 循环 。
3.4 编写程序,生成一个包含 50 个随机整数的列表,然后删除其中所有奇数。(提示:从后向前删。)
答: Python 3.4.2 代码如下,
import random
x = [random.randint(0,100) for i in range(50)]
print(x)
i = len(x)-1
while i>=0:
if x[i]%2==1:
del x[i]
i-=1
print(x)
3.5 编写程序,生成一个包含 20 个随机整数的列表,然后对其中偶数下标的元素进行降序排列,奇数下标的元素不变。(提示:使用切片。)
答: Python 3.4.2 代码如下,
import random
x = [random.randint(0,100) for i in range(20)]
print(x)
y = x[::2]
y.sort(reverse=True)
x[::2] = y
print(x)
3.6 编写程序,用户从键盘输入小于 1000 的整数,对其进行因式分解。例如, 10=2 × 5 , 60=2 × 2 × 3 × 5 。
答:
1 ) Python 3.4.2 代码
x = input('Please input an integer less than 1000:')
x = eval(x)
t = x
i = 2
result = []
while True:
if t==1:
break
if t%i==0:
result.append(i)
t = t/i
else:
i+=1
print(x,'=','*'.join(map(str,result)))
2 ) Python 2.7.8 代码
x = input('Please input an integer less than 1000:')
t = x
i = 2
result = []
while True:
if t==1:
break
if t%i==0:
result.append(i)
t = t/i
else:
i+=1
print x,'=','*'.join(map(str,result))
3.7 编写程序 , 至少使用 2 种不同的方法计算 100 以内所有奇数的和。
答 : Python 3.4.2 代码如下 , 如果使用 Python 2.7.8 只需要把其中的 print() 函数改为 print 语句即可。
x = [i for i in range(1,100) if i%2==1]
print(sum(x))
print(sum(range(1,100)[::2]))
3.8 编写程序,输出所有由 1 、 2 、 3 、 4 这四个数字组成的素数,并且在每个素数中每个数字只使用一次。
答: Python 3.4.2 代码如下,
答: Python 3.4.2 代码如下,如果使用 Python 2.7.8 只需要把其中的 print() 函数改为 print 语句即可。
x = input('Please input x:')
x = eval(x)
if x<0 or x>=20:
print(0)
elif 0<=x<5:
print(x)
elif 5<=x<10:
print(3*x-5)
elif 10<=x<20:
print(0.5*x-2)
3.9 编写程序,实现分段函数计算,如下表所示。
x |
y |
x<0 |
0 |
0<=x<5 |
x |
5<=x<10 |
3x-5 |
10<=x<20 |
0.5x-2 |
20<=x |
0 |
|
|
答: Python 3.4.2 代码如下,如果使用 Python 2.7.8 只需要把其中的 print() 函数改为 print 语句即可。
x = input('Please input x:')
x = eval(x)
if x<0 or x>=20:
print(0)
elif 0<=x<5:
print(x)
elif 5<=x<10:
print(3*x-5)
elif 10<=x<20:
print(0.5*x-2)
第 4 章 字符串与正则表达式
4.1 假设有一段英文,其中有单独的字母“ I ”误写为“ i ”,请编写程序进行纠正。
答:这里给出 Python 3.4.2 代码,如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
1 )不使用正则表达式
x = "i am a teacher,i am man, and i am 38 years old.I am not a businessman."
x = x.replace('i ','I ')
x = x.replace(' i ',' I ')
print(x)
2 )使用正则表达式
x = "i am a teacher,i am man, and i am 38 years old.I am not a businessman."
import re
pattern = re.compile(r'(?:[^\w]|\b)i(?:[^\w])')
while True:
result = pattern.search(x)
if result:
if result.start(0) != 0:
x = x[:result.start(0)+1]+'I'+x[result.end(0)-1:]
else:
x = x[:result.start(0)]+'I'+x[result.end(0)-1:]
else:
break
print(x)
4.2 假设有一段英文,其中有单词中间的字母“ i ”误写为“ I ”,请编写程序进行纠正。
答:这里给出 Python 3.4.2 代码,如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
import re
x = "I am a teacher,I am man, and I am 38 years old.I am not a busInessman."
print(x)
pattern = re.compile(r'(?:[\w])I(?:[\w])')
while True:
result = pattern.search(x)
if result:
if result.start(0) != 0:
x = x[:result.start(0)+1]+'i'+x[result.end(0)-1:]
else:
x = x[:result.start(0)]+'i'+x[result.end(0)-1:]
else:
break
print(x)
4.3 有一段英文文本,其中有单词连续重复了 2 次,编写程序检查重复的单词并只保留一个。例如文本内容为“ This is is a desk. ”,程序输出为“ This is a desk. ”
答:这里给出 Python 3.4.2 代码,如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
1 )方法一
import re
x = 'This is a a desk.'
pattern = re.compile(r'\b(\w+)(\s+\1){1,}\b')
matchResult = pattern.search(x)
x = pattern.sub(matchResult.group(1),x)
print(x)
2 )方法二
x = 'This is a a desk.'
pattern = re.compile(r'(?P
matchResult = pattern.search(x)
x = x.replace(matchResult.group(0),matchResult.group(1))
4.4 简单解释 Python 的字符串驻留机制。
答:
Python 支持字符串驻留机制,即:对于短字符串,将其赋值给多个不同的对象时,内存中只有一个副本,多个对象共享该副本。这一点不适用于长字符串,即长字符串不遵守驻留机制,下面的代码演示了短字符串和长字符串在这方面的区别。
>>> a = '1234'
>>> b = '1234'
>>> id(a) == id(b)
True
>>> a = '1234'*50
>>> b = '1234'*50
>>> id(a) == id(b)
False
4.5 编写程序,用户输入一段英文,然后输出这段英文中所有长度为 3 个字母的单词。
答:这里给出 Python 3.4.2 代码,如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
import re
x = input('Please input a string:')
pattern = re.compile(r'\b[a-zA-Z]{3}\b')
print(pattern.findall(x))
第 5 章 函数设计与使用
5.1 运行 5.3.1 小节最后的示例代码,查看结果并分析原因。
答:原因是对于函数的默认值参数只会被处理一次,下次再调用函数并且不为默认值参数赋值时会继续使用上一次的结果,对于列表这样的结构,如果调用函数时为默认值参数的列表插入或删除了元素,将会得到保留,从而影响下一次调用。
5.2 编写函数,判断一个整数是否为素数,并编写主程序调用该函数。
答:这里给出 Python 3.4.2 代码,如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
import math
def IsPrime(v):
n = int(math.sqrt(v)+1)
for i in range(2,n):
if v%i==0:
return 'No'
else:
return 'Yes'
print(IsPrime(37))
print(IsPrime(60))
print(IsPrime(113))
5.3 编写函数,接收一个字符串,分别统计大写字母、小写字母、数字、其他字符的个数,并以元组的形式返回结果。
答:这里给出 Python 3.4.2 代码,如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
def demo(v):
capital = little = digit = other =0
for i in v:
if 'A'<=i<='Z':
capital+=1
elif 'a'<=i<='z':
little+=1
elif '0'<=i<='9':
digit+=1
else:
other+=1
return (capital,little,digit,other)
x = 'capital = little = digit = other =0'
print(demo(x))
5.4 在函数内部可以通过关键字 global 来定义全局变量。
5.5 如果函数中没有 return 语句或者 return 语句不带任何返回值,那么该函数的返回值为 None 。
5.6 调用带有默认值参数的函数时,不能为默认值参数传递任何值,必须使用函数定义时设置的默认值。(对、 错 )
5.7 在 Python 程序中,局部变量会隐藏同名的全局变量吗?请编写代码进行验证。
答案:会。
>>> def demo():
a=3
print a
>>> a=5
>>> demo()
3
>>> a
5
5.8 lambda 表达式只能用来创建匿名函数,不能为这样的函数起名字。(对、 错 )
5.9 编写函数,可以接收任意多个整数并输出其中的最大值和所有整数之和。
答:这里给出 Python 3.4.2 代码,如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
def demo(*v):
print(v)
print(max(v))
print(sum(v))
demo(1,2,3)
demo(1,2,3,4)
demo(1,2,3,4,5)
5.10 编写函数 , 模拟内置函数 sum() 。
答 : 这里给出 Python 3.4.2 代码 , 如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
def Sum(v):
s = 0
for i in v:
s += i
return s
x = [1,2,3,4,5]
print(Sum(x))
x = (1,2,3,4,5)
print(Sum(x))
5.11 包含 yield 语句的函数可以用来创建生成器。
5.12 编写函数,模拟内置函数 sorted() 。
答:这里给出 Python 3.4.2 代码,如果使用 Python 2.7.8 的话只需要修改其中的 print() 函数为 print 语句即可。
def Sorted(v):
t = v[::]
r = []
while t:
tt = min(t)
r.append(tt)
t.remove(tt)
return r
x = [1,3,5,2,1,0,9,7]
print(x)
print(Sorted(x))
第 6 章 面向对象程序设计
6.1 继承 6.5 节例 2 中的 Person 类生成 Student 类,填写新的函数用来设置学生专业,然后生成该类对象并显示信息。
答: Python 3.4.2 代码为
import types
class Person(object): # 基类必须继承于 object ,否则在派生类中将无法使用 super() 函数
def __init__(self, name = '', age = 20, sex = 'man'):
self.setName(name)
self.setAge(age)
self.setSex(sex)
def setName(self, name):
if not isinstance(name,str):
print('name must be string.')
return
self.__name = name
def setAge(self, age):
if not isinstance(age,int):
print('age must be integer.')
return
self.__age = age
def setSex(self, sex):
if sex != 'man' and sex != 'woman':
print('sex must be "man" or "woman"')
return
self.__sex = sex
def show(self):
print(self.__name)
print(self.__age)
print(self.__sex)
class Student(Person):
def __init__(self, name='', age = 30, sex = 'man', major = 'Computer'):
# 调用基类构造方法初始化基类的私有数据成员
super(Student, self).__init__(name, age, sex)
self.setMajor(major) # 初始化派生类的数据成员
def setMajor(self, major):
if not isinstance(major, str):
print('major must be a string.')
return
self.__major = major
def show(self):
super(Student, self).show()
print(self.__major)
if __name__ =='__main__':
zhangsan = Person('Zhang San', 19, 'man')
zhangsan.show()
lisi = Student('Li Si',32, 'man', 'Math')
lisi.show()
6.2 设计一个三维向量类,并实现向量的加法、减法以及向量与标量的乘法和除法运算。
答: Python 3.4.2 代码如下
class Vecter3:
def __init__(self, x=0, y=0, z=0):
self.X = x
self.Y = y
self.Z = z
def __add__(self, n):
r = Vecter3()
r.X = self.X + n.X
r.Y = self.Y + n.Y
r.Z = self.Z + n.Z
return r
def __sub__(self, n):
r = Vecter3()
r.X = self.X - n.X
r.Y = self.Y - n.Y
r.Z = self.Z - n.Z
return r
def __mul__(self, n):
r = Vecter3()
r.X = self.X * n
r.Y = self.Y * n
r.Z = self.Z * n
return r
def __truediv__(self, n):
r = Vecter3()
r.X = self.X / n
r.Y = self.Y / n
r.Z = self.Z / n
return r
def __floordiv__(self, n):
r = Vecter3()
r.X = self.X // n
r.Y = self.Y // n
r.Z = self.Z // n
return r
def show(self):
print((self.X,self.Y,self.Z))
v1 = Vecter3(1,2,3)
v2 = Vecter3(4,5,6)
v3 = v1+v2
v3.show()
v4 = v1-v2
v4.show()
v5 = v1*3
v5.show()
v6 = v1/2
v6.show()
6.3 面向对象程序设计的三要素分别为 封装 、 继承 和 多态 。
6.4 简单解释 Python 中以下划线开头的变量名特点。
答:
在 Python 中,以下划线开头的变量名有特殊的含义,尤其是在类的定义中。用下划线作为变量前缀和后缀来表示类的特殊成员:
● _xxx :这样的对象叫做保护变量,不能用 'from module import *' 导入,只有类对象和子类对象能访问这些变量;
● __xxx__ :系统定义的特殊成员名字;
● __xxx :类中的私有成员,只有类对象自己能访问,子类对象也不能访问到这个成员,但在对象外部可以通过“对象名 ._ 类名 __xxx ”这样的特殊方式来访问。 Python 中没有纯粹的 C++ 意义上的私有成员。
6.5 与运算符“ ** ”对应的特殊方法名为 __pow__() ,与运算符“ // ”对应的特殊方法名为 __floordiv__() 。
6.6 假设 a 为类 A 的对象且包含一个私有数据成员“ __value ”,那么在类的外部通过对象 a 直接将其私有数据成员“ __value ”的值设置为 3 的语句可以写作 a._A__value 。
第 7 章 文件操作
7.1 假设有一个英文文本文件,编写程序读取其内容,并将其中的大写字母变为小写字母,小写字母变为大写字母。
答:
f = open(r'd:\1.txt','r')
s = f.readlines()
f.close()
r = [i.swapcase() for i in s]
f = open(r'd:\2.txt','w')
f.writelines(r)
f.close()
7.2 编写程序,将包含学生成绩的字典保存为二进制文件,然后再读取内容并显示。
答: Python 3.4.2 代码
import pickle
d = {' 张三 ':98,' 李四 ':90,' 王五 ':100}
print(d)
f = open('score.dat','wb')
pickle.dump(1,f)
pickle.dump(d,f)
f.close
f = open('score.dat','rb')
pickle.load(f)
d = pickle.load(f)
f.close()
print(d)
7.3 使用 shutil 模块中的 move() 方法进行文件移动。
答:
>>> import shutil
>>> shutil.move(r'd:\1.txt', r'e:\1.txt')
'e:\\1.txt'
7.4 简单解释文本文件与二进制文件的区别。
答:
( 1 )文本文件
文本文件存储的是常规字符串,由若干文本行组成,通常每行以换行符 '\n' 结尾。常规字符串是指记事本或其他文本编辑器能正常显示、编辑并且人类能够直接阅读和理解的字符串,如英文字母、汉字、数字字符串。文本文件可以使用字处理软件如 gedit 、记事本进行编辑。
( 2 )二进制文件
二进制文件把对象内容以字节串 (bytes) 进行存储,无法用记事本或其他普通字处理软件直接进行编辑,通常也无法被人类直接阅读和理解,需要使用专门的软件进行解码后读取、显示、修改或执行。常见的如图形图像文件、音视频文件、可执行文件、资源文件、各种数据库文件、各类 office 文档等都属于二进制文件。
7.5 编写代码,将当前工作目录修改为“ C:\ ”,并验证,最后将当前工作目录恢复为原来的目录。
答 :
>>> import os
>>> os.getcwd()
'C:\\Python34'
>>> os.chdir(r'c:\\')
>>> os.getcwd()
'c:\\'
>>> os.chdir(r'c:\Python34')
>>> os.getcwd()
'c:\\Python34'
7.6 编写程序,用户输入一个目录和一个文件名,搜索该目录及其子目录中是否存在该文件。
答:
1 ) Python 3.4.2 代码
import sys
import os
directory = sys.argv[1]
filename = sys.argv[2]
paths = os.walk(directory)
for root,dirs,files in paths:
if filename in files:
print('Yes')
break
else:
print('No')
2 ) Python 2.7.8 代码
import sys
import os
directory = sys.argv[1]
filename = sys.argv[2]
paths = os.walk(directory)
for root,dirs,files in paths:
if filename in files:
print 'Yes'
break
else:
print 'No'
7.7 文件对象的 flush() 方法用来把缓冲区的内容写入文件,但不关闭文件。
7.8 os.path 模块中的 isfile() 方法用来测试指定的路径是否为文件。
7.9 os 模块的 listdir() 方法用来返回包含指定文件夹中所有文件和子文件夹的列表。
第 8 章 异常处理结构与程序调试
8.1 Python 异常处理结构有哪几种形式?
答:
比较常用的形式有:
1 )标准异常处理结构
try:
try 块 # 被监控的语句,可能会引发异常
except Exception[, reason]:
except 块 # 处理异常的代码
如果需要捕获所有异常时,可以使用 BaseException ,代码格式如下:
try:
……
except BaseException, e:
except 块 # 处理所有错误
上面的结构可以捕获所有异常,尽管这样做很安全,但是一般并不建议这样做。对于异常处理结构,一般的建议是尽量显式捕捉可能会出现的异常并且有针对性地编写代码进行处理,因为在实际应用开发中,很难使用同一段代码去处理所有类型的异常。当然,为了避免遗漏没有得到处理的异常干扰程序的正常执行,在捕捉了所有可能想到的异常之后,您也可以使用异常处理结构的最后一个 except 来捕捉 BaseException 。
2 )另外一种常用的异常处理结构是 try...except...else... 语句。
3 )在实际开发中,同一段代码可能会抛出多个异常,需要针对不同的异常类型进行相应的处理。为了支持多个异常的捕捉和处理, Python 提供了带有多个 except 的异常处理结构,这类似于多分支选择结构,一旦某个 except 捕获了异常,则后面剩余的 except 子句将不会再执行。语法为:
try:
try 块 # 被监控的语句
except Exception1:
except 块 1 # 处理异常 1 的语句
except Exception2:
except 块 2 # 处理异常 2 的语句
4 )将要捕获的异常写在一个元组中,可以使用一个 except 语句捕获多个异常,并且共用同一段异常处理代码,当然,除非确定要捕获的多个异常可以使用同一段代码来处理,并不建议这样做。
5 )最后一种常用的异常处理结构是 try...except...finally... 结构。在该结构中, finally 子句中的内存无论是否发生异常都会执行,常用来做一些清理工作以释放 try 子句中申请的资源。语法如下:
try:
……
finally:
...... # 无论如何都会执行的代码
8.2 异常和错误有什么区别?
答:
异常是指因为程序执行过程中出错而在正常控制流以外采取的行为。严格来说,语法错误和逻辑错误不属于异常,但有些语法错误往往会导致异常,例如由于大小写拼写错误而访问不存在的对象,或者试图访问不存在的文件,等等。
8.3 使用 pdb 模块进行 Python 程序调试主要有哪几种用法?
答:主要有三种方式,
1 )在交互模式下使用 pdb 模块提供的功能可以直接调试语句块、表达式、函数等多种脚本。
2 )在程序中嵌入断点来实现调试功能
在程序中首先导入 pdb 模块,然后使用 pdb.set_trace() 在需要的位置设置断点。如果程序中存在通过该方法调用显式插入的断点,那么在命令提示符环境下执行该程序或双击执行程序时将自动打开 pdb 调试环境,即使该程序当前不处于调试状态。
3 )使用命令行调试程序
在命令行提示符下执行“ python –m pdb 脚本文件名”,则直接进入调试环境;当调试结束或程序正常结束以后, pdb 将重启该程序。
8.4 Python 内建异常类的基类是 BaseException 。
8.5 断言语句的语法为 assert 。
8.6 Python 上下文管理语句是 with 。
第 9 章 GUI 编程
9.1 设计一个窗体,并放置一个按钮,单击按钮后弹出颜色对话框,关闭颜色对话框后提示选中的颜色。
答: Python 2.7.8 代码如下,
import wx
class wxGUI(wx.App):
def OnInit(self):
frame = wx.Frame(parent=None, title='wxGUI', size=(160,140))
panel = wx.Panel(frame, -1)
buttonOK = wx.Button(panel, -1, 'OK', pos=(0,0))
self.Bind(wx.EVT_BUTTON, self.OnButtonOK, buttonOK)
frame.Show()
return True
def OnButtonOK(self, event):
colorDlg = wx.ColourDialog(None)
colorDlg.ShowModal()
color = colorDlg.GetColourData().Colour
wx.MessageBox(str(color))
app = wxGUI()
app.MainLoop()
9.2 设计一个窗体,并放置一个按钮,按钮默认文本为“开始”,单击按钮后文本变为“结束”,再次单击后变为“开始”,循环切换。
答: Python 2.7.8 代码如下,
import wx
class wxGUI(wx.App):
def OnInit(self):
frame = wx.Frame(parent=None, title='wxGUI', size=(160,140))
panel = wx.Panel(frame, -1)
self.buttonOK = wx.Button(panel, -1, 'Start', pos=(0,0))
self.Bind(wx.EVT_BUTTON, self.OnButtonOK, self.buttonOK)
frame.Show()
return True
def OnButtonOK(self, event):
text = self.buttonOK.GetLabelText()
if text == 'Start':
self.buttonOK.SetLabelText('End')
elif text == 'End':
self.buttonOK.SetLabelText('Start')
app = wxGUI()
app.MainLoop()
9.3 设计一个窗体,模拟 QQ 登录界面,当用户输入号码 123456 和密码 654321 时提示正确,否则提示错误。
答: Python 2.7.8 代码如下,
import wx
class wxGUI(wx.App):
def OnInit(self):
frame = wx.Frame(parent=None, title='Login', size=(250,150), pos=(350,350))
panel = wx.Panel(frame, -1)
label1 = wx.StaticText(panel, -1, 'UserName:', pos=(0,10), style=wx.ALIGN_RIGHT)
label2 = wx.StaticText(panel, -1, 'Password:', pos=(0,30), style=wx.ALIGN_RIGHT)
self.textName = wx.TextCtrl(panel, -1, pos=(70,10), size=(160,20))
self.textPwd = wx.TextCtrl(panel, -1, pos=(70,30), size=(160,20),style=wx.TE_PASSWORD)
buttonOK = wx.Button(panel, -1, 'OK', pos=(30,60))
self.Bind(wx.EVT_BUTTON, self.OnButtonOK, buttonOK)
buttonCancel = wx.Button(panel, -1, 'Cancel', pos=(120,60))
self.Bind(wx.EVT_BUTTON, self.OnButtonCancel, buttonCancel)
buttonOK.SetDefault()
frame.Show()
return True
def OnButtonOK(self, event):
usrName = self.textName.GetValue()
usrPwd = self.textPwd.GetValue()
if usrName=='123456' and usrPwd=='654321':
wx.MessageBox('Right')
else:
wx.MessageBox('Wrong')
def OnButtonCancel(self, event):
pass
app = wxGUI()
app.MainLoop()