1 python
2
3 变量的命名和使用
4
5 · 变量名只能包含字母、数字和下划线。不能以数字打头。
6 · 变量名不能包含空格,但可使用下划线来分隔其中的单词。
7 · 不要将Python关键字和函数名用作变量名。
8 · 慎用小写字母l和大写字母O,因为它们可能被人错看成数字1和0。
9
10 列表、元组、集合、字典的区别是什么?
11
12 列表:元素可变(任何数据类型),有序(可索引),append/insert/pop;
13 元组:元素不可变,但元素中的可变元素是可变的;有序(可索引);而且元组可以被散列,例如作为字典的键。
14 集合:无序(不可被索引)、互异
15 字典:无序,键值对(key:value),key唯一不可重复
16
17 # -*- coding: utf-8 -*-
18
19 一、变量
20
21 #变量使用、空格引用、字符大小写、字符首字母大写、应用数值str()
22 first_name = "zhang"
23 last_name = "shan"
24 full_name = first_name+" "+last_name
25
26 print(full_name.upper())
27
28 print(full_name.lower())
29
30 name = "hello, "+full_name.title()+"!"
31 print(name)
32
33 age = "24"
34 message = full_name.title()+" is "+str(age)+" years old ! "
35 print(message)
36
37 #制表符和换行符
38 languages = "languages\t:\nc\nc++\npython\nphp\nperl"
39 print(languages)
40
41 #剔除空格
42 string = ' python '
43 #右侧空格剔除
44 print(string.rstrip())
45 #左侧空格剔除
46 print(string.lstrip())
47 #左右剔除
48 print(string.strip())
49
50 #计算加、乘、除、幂
51 print(5+2)
52 print(5*2)
53 print(5.0/2)
54 print(2**3)
55
56 二、列表
57
58 #列表
59 print("列表")
60 name = ["zhangfei","liubei","guanyu"]
61 print(name)
62
63 print("修改列表元素")
64 name[0]="sunshangxiang"
65 print(name)
66
67 print("在列表中添加元素到末尾")
68 name.append("zhaoyun")
69 print(name)
70
71 print("列表中插入元素")
72 name.insert(1,"zhugeliang")
73 print(name)
74
75 print("列表中删除元素")
76 print("1、del删除后无法访问")
77 del name[1]
78 print(name)
79
80 print("2、pop()任意位置删除后可使用\npop()删除列表末尾=弹出栈顶元素\n()中可填0、1...可弹出任意位置元素\nname.pop()后将删除元素引用到popped_name")
81 popped_name = name.pop()
82 print(name)
83
84 print("查看popped_name")
85 print(popped_name)
86
87 print("3、remove()根据值删除元素后可使用\n注:只删除第一次出现的值,若出现多次,需循环\n如:删除刘备")
88 removed_name = 'liubei'
89 name.remove(removed_name)
90 print(name)
91
92 print("查看removed_name")
93 print(removed_name)
94
95 print("\n")
96
97 #组织列表
98 print("新列表")
99 word = ['c','s','d','n','a']
100 print(word)
101
102 print("1、sort()排序,排序后无法恢复")
103 word.sort()
104 print(word)
105
106 print("sort(reverse=True),逆序")
107 word = ['c','s','d','n','a']
108 print(word)
109 word.sort(reverse=True)
110 print(word)
111
112 print("sorted()排序后不影响原列表,可以使用sorted(reverse=True)逆序==》不做例。")
113
114
115 print("\n")
116 print("2、reverse()不排序,直接反转列表元素,永久性但可再次reverse()恢复")
117 print("原列表与reverse后的列表")
118 word = ['c','s','d','n','a']
119 print(word)
120 word.reverse()
121 print(word)
122
123 print("\n")
124 print("len(列表名)确定列表长度,\n例:len(word)")
125 word = ['c','s','d','n','a']
126 print(word)
127 length = "len(word):"+str(len(word))
128 print(length)
129
130 print("打印最后一个元素,例:print(word[-1])")
131 print(word[-1])
132
133
134 三、操作列表(for语句)
135
136 #操作列表
137 print("1、for遍历列表")
138 names = ['lubu','dainwei','daiochan','si','wu']
139 for name in names:
140 print(name)
141
142 print("\n2、缩进循环,不缩进只执行一次,'for语句后首行要缩进'.")
143 for name in names:
144 print("hello "+name.title()+" !")
145 print("Thank you,everyone !")
146
147 print("\n函数range(),例:range(1,6)打印1-5.")
148 for value in range(1,6):
149 print(value)
150
151 print("\n使用range()创建数字列表")
152 numbers = list(range(1,6))
153 print(numbers)
154
155 print("\nrange()可指定步长")
156 numbers1 = list(range(1,11,2))
157 print(numbers1)
158
159 print("\n1~10的平方")
160 #为了使代码简洁,可直接number2.append(value**2)
161 numbers2 = []
162 for value in range(1,11):
163 numbers3 = value**2
164 numbers2.append(numbers3)
165 print(numbers2)
166
167 print("\n将上述数字列表简单统计计算\n最小值为:")
168 print(min(numbers2))
169 print("\n最大值为:")
170 print(max(numbers2))
171 print("\n总和:")
172 print(sum(numbers2))
173
174 print("\n列表解析")
175 numbers4 = [value**2 for value in range(1,11)]
176 print(numbers4)
177
178 print("\n使用列表中多个元素\n1、切片:切取列表中前三个数字,和最后三个")
179 print(numbers4[0:3])
180 print(numbers4[-3:])
181
182 print("\n遍历切片,遍历前三个数字")
183 for value in numbers4[:3]:
184 print(value)
185
186 print("\n复制列表,若想复制的表不一样,可分别在每个表中修改后引用")
187 print(names)
188 names1 = names[:]
189 print(names1)
190 print("names1 = names 不可实现上述情况,此为两表关联,两表值绝对一致")
191
192 print("\n定义元组,元组元素不可修改,但可变量赋值,重新定义整个元组:")
193 dimensions = (200,50)
194 for dimension in dimensions:
195 print(dimension)
196 dimensions = (400,100)
197 for dimension in dimensions:
198 print(dimension)
199
200 print("\n代码规范:\nPEP 8建议每级缩进都使用四个空格\n很多Python程序员都建议每行不超过80>字符\n不要在程序文件中过多地使用空行")
201
202
203 四、操作字典(for语句、if语句)
204 # 字典
205 people = {'color':'green','points':5}
206 print(people['color'])
207 print(people['points'])
208
209 # 字典应用【场景:射杀绿色,获得5点】
210 people = {'color':'green','points':5}
211 new_points = people['points']
212 print("you just earned "+str(new_points)+" points!")
213
214 # 字典新增键值对
215 people = {'color':'black','points':'6'}
216 print(people)
217 people['name'] = "laozhang"
218 people['sex'] = "man"
219 print(people)
220
221 # 定义空字典,添加键值对
222 class1 = {}
223 class1['name1'] = "zhngfei"
224 class1['name2'] = "liubei"
225 print(class1)
226
227 # 修改字典中的值
228 peopel = {'color':'green','points':'2'}
229 print("The people is "+people['color']+".")
230 people['color'] = 'yellow'
231 print("The people is now "+people['color']+".")
232
233 # 例子:定初始速度级别,跟踪一个能够以某级别速度移动的人的位置,记录移动后的位置
234 alien_0 = {'x_position': 0,'y_position': 10,'speed':'quick'}
235 print("Original x_position:"+str(alien_0['x_position']))
236 # 向右移动人
237 # 根据people的当前速度决定将其移动多远
238 if alien_0['speed'] == 'slow':
239 x_increment = 1
240 elif alien_0['speed'] == 'quick':
241 x_increment = 2
242 else:
243 # 这个alien的speed很快
244 x_increment = 3
245 # 新位置=老位置加上增量
246 alien_0['x_position'] = alien_0['x_position']+x_increment
247 print("New x_position:"+str(alien_0['x_position']))
248
249 # 删除键值对
250 people = {'color':'green','points':5}
251 print(people)
252 del people['points']
253 print(people)
254
255 # 由类似对象组成的字典
256 favorite_languages = {
257 'zhangfei':'python',
258 'liubei':'c',
259 'guanyu':'go',
260 }
261 print("liubei's favorite language is "+favorite_languages['guanyu'].title()+".")
262
263 # 遍历字典
264 user = {
265 'zhang':'fei',
266 'liu':'bei',
267 'guan':'yu',
268 }
269 print("\n学生姓名:")
270 for xing,ming in user.items():
271 print("\nxing:"+xing.title())
272 print("ming:"+ming)
273 print(xing.title()+ming)
274
275 for name,language in favorite_languages.items():
276 print(name.title()+"'s favorite language is "+ language.title()+".")
277
278 # 遍历字典中的所有键
279 favorite_languages = {
280 'zhangfei':'python',
281 'liubei':'c',
282 'guanyu':'go',
283 'sunshangxiang':'java'
284 }
285 for name in favorite_languages.keys():
286 print(name.title())
287
288 # 字典列表组合使用(占用上一个字典内容)
289 friends = ['liubei','sunshangxiang']
290
291 for name in favorite_languages.keys():
292 print(name.title())
293 if name in friends:
294 print("hi,"+name.title()+",I see your favorite language is "+favorite_languages[name].title()+"!")
295
296
297 # 查看字典中是否存在该键
298 if 'zhaoyun' not in favorite_languages.keys():
299 print("zhaoyun,啥都不喜欢!")
300
301 # 按顺序遍历字典
302 for name in sorted(favorite_languages.keys()):
303 print(name.title()+",hello!")
304
305 # 遍历字典中的所有值
306 print("The following languages have been mentioned:")
307 for language in favorite_languages.values():
308 print(language.title())
309
310 # 提取字典中的值,并去重
311 favorite_languages = {
312 'huangzhong':'python',
313 'zhaoyun':'c++',
314 'lubu':'java',
315 'dianwei':'python',
316 'hanxin':'C++',
317 }
318 print("The following languages have been mentioned:")
319 for language in set(favorite_languages.values()):
320 print(language.title())
321
322 # 嵌套
323 # 字典列表
324 alien_0 = {'color':'green','point':4}
325 alien_1 = {'color':'yellow','point':6}
326 alien_2 = {'color':'red','point':7}
327 aliens = [alien_0,alien_1,alien_2]
328 for alien in aliens:
329 print(alien)
330
331 # 创建空列表
332 print("创建外星人列表")
333 aliens = []
334 # 创建6个黄色的外星人
335 for alien_number in range(6):
336 new_alien = {'color':'yellow','points':5,'speed':'slow'}
337 aliens.append(new_alien)
338 # 显示前四个外星人
339 for alien in aliens[:4]:
340 print(alien)
341 print("...")
342 # 显示创建了多少个外星人
343 print("Total number of aliens:"+str(len(aliens)))
344
345 # 创建空列表,并修改列表一部分字段
346 print("创建外星人列表1")
347 aliens_1 = []
348 # 创建10个绿色的外星人
349 for people_number in range(10):
350 new_people = {'color':'green','points':5,'speed':'slow'}
351 aliens_1.append(new_people)
352 for people in aliens_1[0:3]:
353 if people['color'] == 'green':
354 people['color'] = 'red'
355 people['speed'] = 'quick'
356 people['points'] = 10
357 # 显示前5个外星人
358 for people in aliens_1[:5]:
359 print(people)
360 print("...")
361
362 # 添加elif语句
363 for people in aliens_1[:10]:
364 if people['color'] == 'red':
365 people['color'] = 'black'
366 people['speed'] = 'stop'
367 people['points'] = '100'
368 elif people['color'] == 'green':
369 people['color'] = 'blue'
370 people['speed'] = 'speedy'
371 people['points'] = '666'
372 for people in aliens_1[:10]:
373 print(people)
374
375 # 在字典中存储列表
376 #(存储所点披萨的信息)
377 pizza = {
378 'crust':'thick',
379 'toppings':['mushrooms','cheese'],
380 }
381 print("概述所点的披萨")
382 print("you ordered a "+pizza['crust']+"-crust pizza "+"with the following toppings: ")
383 for topping in pizza['toppings']:
384 print("\t"+topping)
385
386 # 字典中一个键关联多个值,for循环遍历每个键的所有值
387 print("for循环遍历每个键的所有值")
388 favorite_languages = {
389 'dage':['python','ruby'],
390 'zhangfei':['c','c++'],
391 'zhaoyun':['java'],
392 'huangzhong':['go','java'],
393 }
394 for name,languages in favorite_languages.items():
395 print("\n"+name.title()+"'s favorite languages are: ")
396 for language in languages:
397 print("\t"+language.title())
398
399 #
400 #for name,languages in favorite_languages.items():
401 # print(len(languages))
402 # num = len(languages)
403 # if num == '1':
404 # print("\n"+name.title()+"'s favorite languages is "+languages.title())
405 # elif num != '1':
406 # print("\n"+name.title()+"'s favorite languages are "+languages.title())
407
408 # 字典中存储字典
409
410 users = {
411 'laozhang':{
412 'first':'zhang',
413 'second':'shan',
414 },
415 'laowang':{
416 'first':'wang',
417 'second':'qiang',
418 },
419 }
420
421 for username,user_info in users.items():
422 print("\nusername: "+username)
423 full_name = user_info['first']+" "+user_info['second']
424 print("\t full name: "+full_name.title())
425
426
427 五、用户输入和while循环
428 # -*- coding:utf-8 -*-
429
430 # python 2.7 函数raw_input()== python 3 函数input():将输入解读为字符串。
431 # 用户输入和while循环
432
433 #函数input()--暂停程序,获取用户输入文本,将文本存储在变量中
434
435 message = str(input("Tell me something,and I will repeat it back to you:"))
436 print(message)
437
438 # 打印多行信息
439 prompt = "if you tell us who you are, we can personalize the messages you see."
440 prompt += "\nWhat is your first name?"
441 name = input(prompt)
442 print("\nHello, "+name+"!")
443
444 # 用int()来获取数值输入
445 # 判断身高是否满足要求
446 height = input("How tall are you, in inches?")
447 height = int(height)
448 if height >= 36:
449 print("\nYou're tall enough to ride!")
450 else:
451 print("\nYou'll be able to ride when you're a little ollder.")
452
453 # 求模运算符(判断数值奇偶)
454 number = input("Enter a number, and I'll tell you if it's even or odd: ")
455 number = int(number)
456 if number % 2 == 0:
457 print("\nThe number "+str(number)+" is even.")
458 else:
459 print("\nThe number "+str(number)+" is odd.")
460
461 # while循环简介
462 # while循环1~5
463 current_number = 1
464 while current_number <= 5:
465 print(current_number)
466 current_number+= 1
467
468 # 让用户选择何时退出(定义退岀值)
469 prompt = "\nTell me something, and I will repeat it back to you: "
470 prompt += "\nEnter 'quit' to end the program."
471 message = ""
472 while message != 'quit':
473 message = input(prompt)
474 if message != 'quit':
475 print(message)
476
477 # 使用标志
478 prompt = "\nTell me something, and I will repeat it back to you:"
479 prompt += "\nEnter 'quit' to end the program."
480 active = True
481 while active:
482 message = input(prompt)
483 if message == 'quit':
484 active = False
485 else:
486 print(message)
487
488 # 使用break退出循环(以while True打头的循环(见❶)将不断运行,直到遇到break语句)
489 prompt = "\nPlease enter the name of a city you have visited:"
490 prompt += "\nEnter 'quit' when you are finished."
491 while True:
492 city = input(prompt)
493 if city == 'quit':
494 break
495 else:
496 print("I'd love to go to "+city.title()+"!")
497
498 # 在循环中使用continue(要返回到循环开头,并根据条件测试结果决定是否继续执行循环,可使用continue语句)
499 # 1~10打印奇数
500 current_number = 0
501 while current_number < 10:
502 current_number += 1
503 if current_number % 2 == 0:
504 continue
505 print(current_number)
506
507 # 避免无限循环
508 # (确认程序至少有一个这样的地方能让循环条件为False或让break语句得以执行。)
509
510
511
512 # 使用while循环来处理列表和字典
513 # 一、在列表之间移动元素
514
515 # 首先创建一个待验证的用户列表
516 # 和一个用于存储已验证用户的空列表
517 unconfirmed_users = ['zhangfei','guanyu','liubei']
518 confirmed_users = []
519 # 验证每个用户,知道没有未验证用户为止
520 # 将每一个经过验证的列表都移到已验证用户列表中
521 while unconfirmed_users:
522 current_user = unconfirmed_users.pop()
523 print("Verifying user: "+current_user.title())
524 confirmed_users.append(current_user)
525 # 显示已验证的用户
526 print("\nThe following users have been confirmed: ")
527 for confirmed_user in confirmed_users:
528 print(confirmed_user.title())
529
530 # 使用用户输入来填充字典
531
532 responses = {}
533 # 设置一个标志,指出调查是否继续
534 polling_active = True
535 while polling_active:
536 # 提示输入被调查者名字和回答
537 name = input("\nwhat is your name?")
538 response = input("which mountain would you like to climb someday?")
539 # 将答卷存储在字典中
540 responses[name] = response
541 # 看看是否还有人要参与调查
542 repeat = input("would you like to let another person respond?(yes/no)")
543 if repeat == 'no':
544 polling_active = False
545 # 调查结束,显示结果
546 print("\n--- poll results ---")
547 for name,response in responses.items():
548 print(name+" would like to climb "+response+".")
549
550 六、函数+模块
551
552 # -*- coding: utf-8 -*-
553
554 # 函数
555
556 # 定义函数
557 # (关键字def来告诉Python你要定义一个函数;函数定义,向Python指出了函数名,还可能在括号内指出函数为完成其任务需要什么样的信息---在这里,函数名为greet_user(),它不需要任何信息就能完成其工作,因此括号是空的)
558
559 # 紧跟在def greet_user():后面的所有缩进行构成了函数体。"""文本"""---文档字符串的注释
560
561 def greet_user():
562 """显示简单的问候语"""
563 print("hello!")
564 greet_user()
565
566 # 向函数传递信息
567
568 def greet_user(username):
569 """显示简单的问候语"""
570 print("hello~"+username.title()+"!")
571 greet_user('zhangfei')
572
573 # 实参和形参
574 # 函数greet_user()的定义中,变量username是一个形参——函数完成其工作所需的一项信息;在代码greet_user('jesse')中,值'jesse'是一个实参--实参是调用函数时传递给函数的信息。
575
576 # 位置实参
577 # (你调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。)
578
579 def describe_pet(animal_type,animal_name):
580 """显示宠物信息"""
581 print("\nI have a "+animal_type+".")
582 print("My "+animal_type+"'s name is "+animal_name.title()+".")
583 describe_pet('dog','coco')
584 # 多次调用函数
585 describe_pet('rabbit','dudu')
586
587 # 关键字实参(实参中将名称和值关联起来)
588 def describe_pet(animal_type,animal_name):
589 """显示宠物信息"""
590 print("\nI have a "+animal_type+".")
591 print("My "+animal_type+"'s name is "+animal_name.title()+".")
592 describe_pet(animal_type='dog',animal_name='coco')
593 describe_pet(animal_type='rabbit',animal_name='dudu')
594
595 # 默认值
596 def describe_pet(animal_name,animal_type='dog'):
597 """显示宠物信息"""
598 print("\nI have a "+animal_type+".")
599 print("My "+animal_type+"'s name is "+animal_name.title()+".")
600 describe_pet(animal_name='liao')
601 # 若给animal_type提供了实参,将忽略形参的默认值
602 describe_pet('lisa','rabbit')
603
604 # 等效的函数调用
605 def describe_pet(animal_name,animal_type='dog'):
606 """显示宠物信息"""
607 print("\nI have a "+animal_type+".")
608 print("My "+animal_type+"'s name is "+animal_name.title()+".")
609 describe_pet('liao')
610 describe_pet(animal_name='liao')
611 describe_pet('coco','rabbit')
612 describe_pet(animal_name='coco',animal_type='rabbit')
613 describe_pet(animal_type='rabbit',animal_name='coco')
614
615 # 避免实参错误
616 # traceback指出了问题出在什么地方,确保函数调用和函数定义匹配。
617
618 # 返回值--return语句
619 # 返回简单值(接受名和姓并返回整洁的姓名)
620 def get_formatted_name(first_name,last_name):
621 """返回整洁的姓名"""
622 full_name = first_name+' '+last_name
623 return full_name.title()
624 musician = get_formatted_name('zhang','shan')
625 print("\n"+musician)
626
627 # 让实参变成可选的
628 # 名字有中间名:如张三丰
629 def get_formatted_name(first_name,middle_name,last_name):
630 """返回整洁的姓名"""
631 full_name = first_name+' '+middle_name+' '+last_name
632 return full_name.title()
633 musician = get_formatted_name('zhang','san','feng')
634 print(musician)
635
636 # 若并非所有人都有中间名--中间名可选(指定默认值--空字符串)
637 def get_formatted_name(first_name,last_name,middle_name=''):
638 """返回整洁的姓名"""
639 if middle_name:
640 full_name = first_name+' '+middle_name+' '+last_name
641 else:
642 full_name = first_name+' '+last_name
643 return full_name.title()
644 musician = get_formatted_name('zhao','yun')
645 print(musician)
646 musician = get_formatted_name('zhao','zi','long')
647 print(musician)
648
649 # 返回字典
650 def build_person(first_name,last_name):
651 """返回字典,其中包含有关一个人的信息"""
652 person = {'first':first_name,'last':last_name}
653 return person
654 musician = build_person('huang','zhong')
655 print(musician)
656
657 def build_person(first_name,last_name,age=''):
658 """返回一个字典,其中包含有关一个人的信息"""
659 person = {'first':first_name,'last':last_name}
660 if age:
661 person['age'] = age
662 return person
663 musician = build_person('zhang','fei',age=38)
664 print(musician)
665
666 # 结合使用函数和while循环
667 def get_formatted_name(first_name,last_name):
668 """返回整洁的姓名"""
669 full_name = first_name+' '+last_name
670 return full_name.title()
671 # 这是一个无限循环!
672 while True:
673 print("\nplease tell me your name:")
674 print("(enter 'q' at any time to quit)")
675 f_name = input("first_name:")
676 l_name = input("last_name:")
677 if f_name == 'q' and l_name == 'q':
678 break
679 else:
680 formatted_name = get_formatted_name(f_name,l_name)
681 print("\nhello, "+formatted_name+"!")
682
683 # 传递列表
684 def greet_users(names):
685 """向列表中的每位用户都发出简单的问候"""
686 for name in names:
687 msg = "hello, "+name.title()+"!"
688 print(msg)
689 usernames = ['zhangfei','liubei','guanyu']
690 greet_users(usernames)
691
692 # 在函数中修改列表
693 # 首先创建一个列表,其中包含一些要打印的设计
694 unprinted = ['huawei','oppo','xiaomi']
695 completed_models = []
696 # 模拟打印每个设计,直到没有未打印的设计为止
697 # 打印每个设计后,都将其移到列表completed_models中
698 while unprinted:
699 current = unprinted.pop()
700 # 模拟根据设计制作打印模型的过程
701 print("printing model: "+current)
702 completed_models.append(current)
703 # 显示打印好的所有模型
704 print("\nthe following models have been printed:")
705 for completed_model in completed_models:
706 print(completed_model)
707
708 # 函数引用---第一个负责打印设计的,一个负责概述打印哪些设计
709 def print_models(unprinted,completed_models):
710 """
711 模拟打印每个设计,直到没有未打印的设计为止
712 打印每个设计后,都将其移到列表completed_models中
713 """
714 while unprinted:
715 current = unprinted.pop()
716 # 模拟根据设计制作3D打印模型的过程
717 print("printing model: "+current)
718 completed_models.append(current)
719 def show_completed_models(completed_models):
720 """显示打印好的所有模型"""
721 print("\nthe following models have been printed:")
722 for completed_model in completed_models:
723 print(completed_model)
724 unprinted = ['dog','rabbit','cat']
725 completed_models = []
726 print_models(unprinted,completed_models)
727 show_completed_models(completed_models)
728
729 # 禁止函数修改列表
730 # 可用切片表示法--将列表的副本传递给函数,如:function_name(list_name[:])
731 # print_models(unprinted[:],completed_models)
732
733 # 传递任意数量的实参
734 # (形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中)
735 def make_pizza(*toppings):
736 """打印顾客点的所有配料"""
737 print(toppings)
738 make_pizza('pepperoni')
739 make_pizza('mushrooms','green peppers','extra cheese')
740
741 # 加入循环
742 def make_pizza(size,*toppings):
743 """打印顾客点的所有配料"""
744 print("\nmakeing a "+str(size)+
745 "-inch pizza with the following topping:")
746 for topping in toppings:
747 print("- "+topping)
748 make_pizza('66','pepperoni')
749 make_pizza('99','mushrooms','green peppers','extra cheese')
750
751 # 使用任意数量的关键字实参
752 # (形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所有>名称—值对都封装到这个字典中)
753 def build_profile(first,last,**user_info):
754 """创建一个字典,其中包含我们知道的有关用户的一切"""
755 profile = {}
756 profile['first_name'] = first
757 profile['last_name'] = last
758 for key,value in user_info.items():
759 profile[key] = value
760 return profile
761 user_profile = build_profile('zhang','shan',
762 location='china',
763 field='physics')
764 print(user_profile)
765
766 # 将函数存储在模块中
767 # 导入整个模块
768
769 # cat pizza.py
770 #def make_pizza(size,*toppings):
771 # """概述要制作的披萨"""
772 # print("\nmakeing a "+str(size)+
773 # "-inch pizza with the following toppings:")
774 # for topping in toppings:
775 # print("- "+topping)
776
777 # 在pizza.py所在的目录中创建另一个名为making_pizzas.py的文件,这个文件导入刚创建的模块,再调用make_pizza()两次:
778
779 # cat making_pizzas.py
780 import pizza
781 pizza.make_pizza(16,'pepperoni')
782 pizza.make_pizza(21,'mushrooms','green peppers','extra cheese')
783
784 # import语句可以导入模块中的任何一个函数(模块中有多个函数)
785 # 例如:module_name.function_name()
786
787
788 # 导入特定的函数
789 # 导入方法的语法:from module_name importfunction_name
790 # 逗号分隔函数名,可根据需要从模块中导入任意数量的函数:from module_name importfunction_0,function_1,function_2
791
792 from pizza import make_pizza
793 make_pizza(33,'haha')
794 make_pizza(44,'hehe','hoho','huhu')
795
796 # 使用as给函数指定别名-语法:from module_name importfunction_name as fn
797 # 下面给函数make_pizza()指定了别名mp()。这是在import语句中使用make_pizza asmp实现的,关键字as将函数重命名为你提供的别名
798 from pizza import make_pizza as mp
799 mp(55,'laozhang')
800 mp(66,'laowang','laoli','laohuang')
801
802 # 使用as给模块指定别名-语法:importmodule_name as mn
803 import pizza as p
804 p.make_pizza(77,'coco')
805 p.make_pizza(88,'lili','bobo','popo')
806
807 # 导入模块中的所有函数-语法:from pizza import *
808 # 使用星号(*)运算符可让python导入模块中的所有函数:
809 from pizza import *
810 make_pizza(110,'wowo')
811 make_pizza(220,'qoqo','eoeo','roro')
812
813 七、类
814
815 # -*- coding: utf-8 -*-
816 # 类
817 # 创建和使用类
818 # 创建Dog类(约定,在Python中,首字母大写的名称指的是类)
819 # 1.方法_int_() :类中的函数称为方法,开头和末尾各有两个下划线,这是一种约定.
820 # 在这个方法的定义中,形参self必不可少,还必须位于其他形参的前面---原因:每个与类相关联的方法调用都自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
821
822 # 以self为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量;
823 # self.name = name获取存储在形参name中的值,并将其存储到变量name中,通过实例访问的变量称为属>性;
824
825 class Dog():
826 """一次模拟小狗的简单尝试"""
827 def __init__(self,name,age):
828 """初始化属性name和age"""
829 self.name = name
830 self.age = age
831 def sit(self):
832 """模拟小狗被命令时蹲下"""
833 print(self.name.title()+" is now sitting.")
834 def roll_over(self):
835 """模拟小狗被命令时打滚"""
836 print(self.name.title()+" rolled over!")
837 my_dog = Dog('willie',6)
838 print("my dog's name is "+my_dog.name.title()+".")
839 print("my dog is "+str(my_dog.age)+" years old.")
840 # Python使用实参'willie'和6调用Dog类中的方法__init__()。方法__init__()创建一个表示特定小狗的示例
841
842 # 在Python 2.7中创建类时,需要做细微的修改——在括号内包含单词object:
843 #class classname(object):
844 # --snip--
845
846 # 1.访问属性2.调用方法
847 # 要访问实例的属性,可使用句点表示法,如下代码来访问my_dog的属性name的值:
848 my_dog.name
849 class Dog():
850 """一次模拟小狗的简单尝试"""
851 def __init__(self,name,age):
852 """初始化属性name和age"""
853 self.name = name
854 self.age = age
855 def sit(self):
856 """模拟小狗被命令时蹲下"""
857 print(self.name.title()+" is now sitting.")
858 def roll_over(self):
859 """模拟小狗被命令时打滚"""
860 print(self.name.title()+" rolled over!")
861 my_dog = Dog('willie',6)
862 my_dog.sit()
863 my_dog.roll_over()
864
865 # 使用类和实例--car类
866 class Car():
867 """一次模拟汽车的简单尝试"""
868 def __init__(self,make,model,year):
869 """初始化描述汽车的属性"""
870 self.make = make
871 self.model = model
872 self.year = year
873 def get_descriptive_name(self):
874 """返回整洁的描述性信息"""
875 long_name = str(self.year)+' '+self.make+' '+self.model
876 return long_name.title()
877 my_new_car = Car('audi','a4','2020')
878 print(my_new_car.get_descriptive_name())
879
880 # 给属性指定默认值,添加一个名为odometer_reading的属性,其初始值总是为0;名为read_odometer()的方法,用于读取汽车的里程表
881 class Car():
882 def __init__(self,make,model,year):
883 """初始化描述汽车的属性"""
884 self.make = make
885 self.model = model
886 self.year = year
887 self.odometer_reading = 0
888 def get_descriptive_name(self):
889 """返回整洁的描述性信息"""
890 long_name = str(self.year)+' '+self.make+' '+self.model
891 return long_name.title()
892 def read_odometer(self):
893 """打印一条指出汽车里程的消息"""
894 print("this car has "+str(self.odometer_reading)+" miles on it.")
895 my_new_car = Car('audi','a4',2020)
896 print(my_new_car.get_descriptive_name())
897 my_new_car.read_odometer()
898
899 # 修改属性的值
900 my_new_car = Car('audi','a4',2020)
901 print(my_new_car.get_descriptive_name())
902 my_new_car.odometer_reading = 23
903 my_new_car.read_odometer()
904 # 通过方法修改属性的值
905 class Car():
906 def __init__(self,make,model,year):
907 """初始化描述汽车的属性"""
908 self.make = make
909 self.model = model
910 self.year = year
911 self.odometer_reading = 0
912 def get_descriptive_name(self):
913 """返回整洁的描述性信息"""
914 long_name = str(self.year)+' '+self.make+' '+self.model
915 return long_name.title()
916 def read_odometer(self):
917 """打印一条指出汽车里程的消息"""
918 print("this car has "+str(self.odometer_reading)+" miles on it.")
919 def update_odometer(self,mileage):
920 """将里程表读数设置为指定的值"""
921 self.odometer_reading = mileage
922 my_new_car = Car('audi','a4',2021)
923 print(my_new_car.get_descriptive_name())
924 my_new_car.update_odometer(66)
925 my_new_car.read_odometer()
926
927 # 对方法update_odometer()进行扩展,添加逻辑
928
929 class Car():
930 def __init__(self,make,model,year):
931 """初始化描述汽车的属性"""
932 self.make = make
933 self.model = model
934 self.year = year
935 self.odometer_reading = 0
936 def get_descriptive_name(self):
937 """返回整洁的描述性信息"""
938 long_name = str(self.year)+' '+self.make+' '+self.model
939 return long_name.title()
940 def read_odometer(self):
941 """打印一条指出汽车里程的消息"""
942 print("this car has "+str(self.odometer_reading)+" miles on it.")
943 def update_odometer(self,mileage):
944 """
945 将里程表读数设置为指定的值
946 禁止将里程表读数往回调
947 """
948 if mileage >= self.odometer_reading:
949 self.odometer_reading = mileage
950 else:
951 print("you can't roll back an odometer!")
952 #my_new_car = Car('audi','a4',2021)
953 #print(my_new_car.get_descriptive_name())
954 #my_new_car.update_odometer(-1)
955 #my_new_car.read_odometer()
956
957 # 通过方法对属性的值进行递增
958 def increment_odometer(self,miles):
959 """讲里程表读数曾加指定的量"""
960 self.odometer_reading+= miles
961 my_used_car = Car('subaru','outback',2022)
962 print(my_used_car.get_descriptive_name())
963 my_used_car.update_odometer(5000)
964 my_used_car.read_odometer()
965 my_used_car.increment_odometer(-6000)
966 my_used_car.read_odometer()
967
968
969 # 继承(子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法)
970
971 class Car():
972 """一次模拟汽车的简单尝试"""
973 def __init__(self,make,model,year):
974 self.make = make
975 self.model = model
976 self.year = year
977 self.odometer_reading = 0
978 def get_descriptive_name(self):
979 long_name = str(self.year)+' '+self.make+' '+self.model
980 return long_name.title()
981 def read_odometer(self):
982 print("this car has "+str(self.odometer_reading)+" miles on it.")
983 def update_odometer(self,mileage):
984 if mileage >= self.odometer_reading:
985 self.odometer_reading = mileage
986 else:
987 print("you can't roll back an odometer!")
988 def increment_odometer(self,miles):
989 self.odometer_reading+= miles
990 class ElectricCar(Car):
991 """电动汽车独特之处"""
992 def __init__(self,make,model,year):
993 """初始化父类的属性"""
994 Car.__init__(self,make,model,year)
995 my_tesla = ElectricCar('tesla','model s',2022)
996 print(my_tesla.get_descriptive_name())
997
998 # python2.7中的继承
999 #class Car(object):
1000 # def __init__(self,make,model,year):
1001 # --snip--
1002 #class ElectricCar(Car):
1003 # def __init__(self,make,model,year):
1004 # super(ElectricCar,self).__init__(make,model,year)
1005 # --snip--
1006
1007 # 给子类定义属性和方法
1008
1009 #class Car():
1010 # --snip--
1011 class ElectricCar(Car):
1012 """repersent aspects of a car,sepcific to electric vehicles."""
1013 def __init__(self,make,model,year):
1014 """
1015 电动汽车的独特之处
1016 初始化父类的属性,再初始化电动汽车特有的属性
1017 """
1018 Car.__init__(self,make,model,year)
1019 self.battery_size = 70
1020 def describe_battery(self):
1021 """打印一条描述电瓶容量的消息"""
1022 print("this car has a "+str(self.battery_size)+"-kwh battery.")
1023 my_tesla = ElectricCar('tesla','model s',2020)
1024 print(my_tesla.get_descriptive_name())
1025 print(my_tesla.describe_battery())
1026
1027 # 重写父类的方法(重写fill_gas_tank()的方法:调用该方法则忽略打印下述代码)
1028
1029 class ElectricCar(Car):
1030 def fill_gas_tank():
1031 """电动汽车没有油箱"""
1032 print("this car doesn't need a gas tank!")
1033
1034 # 将实例用作属性(可以将大类中同属性的小类提取出来作为大类中的一个属性)
1035
1036 #class Car():
1037 # --snip--
1038 class Battery():
1039 """一次模拟电动汽车电瓶的简单尝试"""
1040 def __init__(self,battery_size=80):
1041 """初始化电瓶的属性"""
1042 self.battery_size = battery_size
1043 def describe_battery(self):
1044 """打印一条描述电瓶容量的消息"""
1045 print("this car has a "+str(self.battery_size)+"-kwh battery.")
1046 def get_range(self):
1047 """打印一条消息,指出电瓶的续航里程"""
1048 if self.battery_size == 80:
1049 range = 240
1050 elif self.battery_size == 85:
1051 range = 270
1052 message = "this car can go approximately "+str(range)
1053 message+= " miles on a full charge."
1054 print(message)
1055 class ElectricCar(Car):
1056 """电动汽车的独特之处"""
1057 def __init__(self,make,model,year):
1058 """
1059 初始化父类的属性,再初始化电动汽车特有的属性
1060 """
1061 Car.__init__(self,make,model,year)
1062 self.battery = Battery(85)
1063 # 若没有指定尺寸85,则默认值为80
1064 my_tesla = ElectricCar('tesla','model',2023)
1065 print(my_tesla.get_descriptive_name())
1066 my_tesla.battery.describe_battery()
1067 my_tesla.battery.get_range()
1068
1069 # 导入类
1070 # 导入单个类
1071
1072 # cat car.py
1073 # (模块级文档字符串)
1074 #"""一个可用于表示汽车的类"""
1075 #class Car():
1076 # """一次模拟汽车的简单尝试"""
1077 # def __init__(self,make,model,year):
1078 # """初始化描述汽车的属性"""
1079 # self.make = make
1080 # self.model = model
1081 # self.year = year
1082 # self.odometer_reading = 0
1083 # def get_descriptive_name(self):
1084 # """返回整洁的描述性名称"""
1085 # long_name = str(self.year)+' '+self.make+' '+self.model
1086 # return long_name.title()
1087 # def read_odometer(self):
1088 # """打印一条消息,指出汽车的里程"""
1089 # print("this car has "+str(self.odometer_reading)+" miles on it.")
1090 # def update_odometer(self,mileage):
1091 # """
1092 # 讲里程表读数设置为指定的值
1093 # 拒绝将里程表往回拨
1094 # """
1095 # if mileage >= self.odometer_reading:
1096 # self.odometer_reading = mileage
1097 # else:
1098 # print("you can't roll back an odometer!")
1099 # def increment_odometer(self,miles):
1100 # """讲里程表读数增加指定的量"""
1101 # self.odometer_reading+= miles
1102 # ***************************************
1103 # cat my_car.py
1104 #from car import Car
1105 #my_new_car = Car('benchi','c320',2023)
1106 #print(my_new_car.get_descriptive_name())
1107 #my_new_car.odometer_reading = 23
1108 #my_new_car.read_odometer()
1109
1110
1111 # 在一个模块中存储多个类
1112 # cat car.py
1113
1114 #"""一组用于表示燃油汽车和电动汽车的类"""
1115 #class Car():
1116 # --snip--
1117 #class Battrey():
1118 # --snip--
1119 #class ElectricCar(Car):
1120 # --snip--
1121 # ************************
1122 # cat my_electric_car.py
1123 #from car import ElectricCar
1124 #my_tesla = ElectricCar('tesla','model s',2030)
1125 #print(my_tesla.get_descriptive_name())
1126 #my_tesla.battery.describe_battery()
1127 #my_tesla.battery.get_range()
1128
1129 # 从一个模块中导入多个类
1130 # my_cars.py
1131
1132 #from car import Car,ElectricCar
1133 #my_beetle = Car('volkswagen','beetle',2040)
1134 #print(my_beetle.get_descriptive_name())
1135 #my_tesla = ElectricCar('tesla','roadster',2050)
1136 #print(my_tesla.get_get_descriptive_name())
1137
1138 # 导入整个模块
1139 # my_cars.py
1140
1141 #import car
1142 #my_dazhong = car.Car('jieda','dazhong',2010)
1143 #print(my_dazhong.get_descriptive_name())
1144 #my_tesla = car.ElectricCar('tesla','model s',2040)
1145 #print(my_tesla.get_descriptive_name())
1146
1147 # 导入模块中的所有类(不推荐)
1148 #frommodule_name import *
1149
1150 # 在一个模块中导入另一个模块
1151
1152 #cat car.py
1153 #"""一个可用于表示汽车的类"""
1154 #class Car():
1155 # --snip--
1156
1157 #cat electric_car.py
1158 #"""一组可用于表示电动汽车的类"""
1159 #from car import Car
1160 #class Battery():
1161 # --snip--
1162 #class ElectricCar(Car):
1163 # --snip--
1164
1165 # 首先从模块collections中导入了OrderedDict类
1166 # 创建了OrderedDict类的一个实例,并将其存储到favorite_languages中
1167 # 调用OrderedDict()来创建一个空的有序字典,并将其存储在favorite_languages中。
1168 # 接下来,我们以每次一对的方式添加名字—语言对
1169 # 之后我们遍历favorite_languages
1170
1171 from collections import OrderedDict
1172 favorite_languages = OrderedDict()
1173 favorite_languages['jen'] = 'python'
1174 favorite_languages['sarah'] = 'c'
1175 favorite_languages['edward'] = 'ruby'
1176 favorite_languages['phil'] = 'python'
1177 for name,language in favorite_languages.items():
1178 print(name.title()+"'s favorite language is "+ language.title()+".")
1179
1180
1181 八、文件和异常
1182
1183 # -*- coding: utf-8 -*-
1184 # 文件和异常
1185
1186 # 从文件中读取数据
1187 # 读取整个文件
1188 #cat pi_digits.txt
1189 #3.1415926535
1190 # 8979323846
1191 # 2643383279
1192
1193 #cat file_reader.py
1194 # 调用open()和close()来打开和关闭文件,使用方法read()读取这个文件的全部内容存储在contents中
1195 with open('pi_digits.txt') as file_object:
1196 contents = file_object.read()
1197 print(contents)
1198 # 结果多出一个空行(因为read()到达文件末尾时返回一个空字符串),删除空行-可使用rstrip()
1199 print(contents.rstrip())
1200
1201 # 文件路径
1202
1203 # linux中"/"
1204 #with open('text_files/filename.txt') as file_object:
1205 # windows中"\"
1206 #with open('text_files\filename.txt') as file_object:
1207
1208 # 绝对路径一般可能较长,可存储变量中
1209 # linux中
1210 #file_path = '/home/ehmatthes/other_files/text_files/filename.txt'
1211 #with open(file_path) as file_object:
1212 # windows中
1213 #file_path = 'C:\User\ehmatthes\other_files\text_files\filename.txt'
1214 #with open(file_path) as file_object:
1215
1216 # 逐行读取
1217 #cat file_reader.py
1218 filename = '/pi_digits.txt'
1219 with open(filename) as file_object:
1220 for line in file_object:
1221 print(line)
1222
1223 # 创建一个包含文件各行内容的列表
1224 filename = 'pi_digits.txt'
1225 with open(filename) as file_object:
1226 lines = file_object.readlines()
1227 for line in lines:
1228 print(line.rstrip())
1229
1230 # 使用文件的内容
1231 #cat pi_string.py
1232 filename = 'pi_digits.txt'
1233 with open(filename) as file_object:
1234 lines = file_object.readlines()
1235 pi_string = ''
1236 for line in lines:
1237 pi_string+= line.rstrip()
1238 print(pi_string)
1239 print(len(pi_string))
1240
1241 # 去除每行左边的空格--strip()
1242 print("-----")
1243 filename = 'pi_digits.txt'
1244 with open(filename) as file_object:
1245 lines = file_object.readlines()
1246 pi_string = ''
1247 for line in lines:
1248 pi_string+= line.strip()
1249 print(pi_string)
1250 print(len(pi_string))
1251
1252 # 打印到某一位,如打印到小数点后第十位
1253 print(pi_string[:12]+"...")
1254 print(len(pi_string))
1255
1256 # 搜索其中符合自己想要的字符串
1257 birthday = input("enter your birthday, in the form mmddyy: ")
1258 if birthday in pi_string:
1259 print("your birthday appears in the first million digits of pi!")
1260 else:
1261 print("your birthday does not appear in the first million digits of pi.")
1262
1263 # 写入文件
1264 # (调用open()时提供了两个实参,指定读取模式('r')、写入模式('w')、附加模式('a')或让你能够读取和写入文件的模式('r+'))
1265 filename = 'liujinye.txt'
1266 with open(filename,'w') as file_object:
1267 file_object.write("I love liujinye.\n")
1268 # 写入多行
1269 file_object.write("You're my baby !\n")
1270
1271 # 附加到文件(给文件添加内容)
1272 with open(filename,'a') as file_object:
1273 file_object.write("I also love finding meaning in large datasets.\n")
1274
1275 # 异常
1276 # (编写了处理异常的代码,程序将运行;未处理将停止并显示traceback报告)异常是try-except代码处理的
1277
1278 # 处理ZeroDivisionError异常
1279 # cat division.py
1280 #print(5/0)
1281
1282 # 使用try-except代码块
1283
1284 try:
1285 print(5/0)
1286 except ZeroDivisionError:
1287 print("you can't divide by zero !")
1288
1289 # 使用异常避免崩溃
1290 print("Give me two nmubers, and I'll divide them.")
1291 print("Enter 'q' to quit.")
1292 while True:
1293 first_number = input("\nFirst number: ")
1294 if first_number == 'q':
1295 break
1296 second_number = input("Second number:")
1297 if second_number == 'q':
1298 break
1299 try:
1300 answer = int(first_number) / int(second_number)
1301 except ZeroDivisionError:
1302 print("you can't divide by 0 !")
1303 except ValueError:
1304 print("you can't input empty !")
1305 else:
1306 print(answer)
1307
1308 # 处理FileNotFoundError异常
1309
1310 filename = 'empty.txt'
1311 try:
1312 with open(filename) as f_obj:
1313 contents = f_obj.read()
1314 except IOError:
1315 msg = "sorry, the file "+filename+" does not exist."
1316 print(msg)
1317
1318 # 分析文本
1319
1320
1321 filename = 'alice.txt'
1322 try:
1323 with open(filename) as f_obj:
1324 contents = f_obj.read()
1325 except IOError:
1326 msg = "Sorry,the file "+filename+" does not exist."
1327 print(msg)
1328 else:
1329 # 计算文件大致包含多少个单词
1330 words = contents.split()
1331 num_words = len(words)
1332 print("The file "+filename+" has about "+str(num_words)+" words. ")
1333
1334 # 使用多个文件
1335 def count_words(filename):
1336 """计算一个文件大致包含多少个单词"""
1337 try:
1338 with open(filename) as f_obj:
1339 contents = f_obj.read()
1340 except IOError:
1341 msg = "sorry, the file "+filename+" does not exist."
1342 print(msg)
1343 else:
1344 # 计算文件大致包含多少个单词
1345 words = contents.split()
1346 num_words = len(words)
1347 print("the file "+filename+" has about "+str(num_words)+" words. ")
1348 filename = 'alice.txt'
1349 count_words(filename)
1350 filenames = ['alice.txt','/etc/passwd','liujinye','/var/log/messages']
1351 for filename in filenames:
1352 count_words(filename)
1353
1354 # 失败时一声不吭
1355 print("=======失败时不输出=======")
1356 def count_words(filename):
1357 """计算一个文件大致包含多少个单词"""
1358 try:
1359 with open(filename) as f_obj:
1360 contents = f_obj.read()
1361 except IOError:
1362 pass
1363 else:
1364 # 计算文件大致包含多少个单词
1365 words = contents.split()
1366 num_words = len(words)
1367 print("the file "+filename+" has about "+str(num_words)+" words. ")
1368 filename = 'alice.txt'
1369 count_words(filename)
1370 filenames = ['alice.txt','/etc/passwd','liujinye','/var/log/messages']
1371 for filename in filenames:
1372 count_words(filename)
1373
1374 # 使用方法count()来确定特定的单词或短语在字符串中出现了多少次
1375 line = "root,ROOT,Root"
1376 print(line.count('root'))
1377 print(line.lower().count('root'))
1378
1379 # 存储数据
1380
1381 # 使用json.dump()和json.load()
1382 # cat number_write.py
1383 # 使用函数json.dump()将数字列表存储到文件numbers.json中
1384 import json
1385 number = [2,3,5,7,11,13]
1386 filename = 'numbers.json'
1387 with open(filename,'w') as f_obj:
1388 json.dump(number,f_obj)
1389
1390 # 使用json.load()将这个列表读取到内存中:
1391 import json
1392 filename = 'numbers.json'
1393 with open(filename) as f_obj:
1394 numbers = json.load(f_obj)
1395 print(numbers)
1396
1397 # 以上是一种在程序之间共享数据的简单方式。
1398
1399 # 保存和读取用户生成的数据
1400
1401 # 存储用户输入的信息
1402 import json
1403 username = input("What is your name? ")
1404 filename = 'username.json'
1405 with open(filename,'w') as f_obj:
1406 json.dump(username,f_obj)
1407 print("we'll remember you when you come back, "+username+"!")
1408
1409 # 向其名字被存储的用户发出问候
1410
1411 import json
1412 filename = 'username.json'
1413 with open(filename) as f_obj:
1414 username = json.load(f_obj)
1415 print("welcome back , "+username+"!")
1416
1417
1418 # 合并
1419 import json
1420 # 如果以前存储了用户名,就加载它
1421 # 否则,就提示用户输入用户名并存储它
1422 filename = 'username.json'
1423 try:
1424 with open(filename) as f_obj:
1425 username = json.load(f_obj)
1426 except IOError:
1427 username = input("what is your name? ")
1428 with open(filename,'w') as f_obj:
1429 json.dump(username,f_obj)
1430 print("we'll remember you when you come back, "+username+"!")
1431 else:
1432 print("welcome back , "+username+"!")
1433
1434 print("=======================")
1435 # 重构(将上述合并内容,重构定义函数,每个函数一个任务)
1436 import json
1437 def get_stored_username():
1438 """如果存储了用户名,就获取它"""
1439 filename = 'username.json'
1440 try:
1441 with open(filename) as f_obj:
1442 username = json.load(f_obj)
1443 except IOError:
1444 return None
1445 else:
1446 return username
1447 def get_new_username():
1448 """提示用户输入用户名"""
1449 username = input("what is your name? ")
1450 filename = 'username.json'
1451 with open(filename,'w') as f_obj:
1452 json.dump(username,f_obj)
1453 return username
1454 def greet_user():
1455 """问候用户,并指出其名字"""
1456 username = get_stored_username()
1457 if username:
1458 print("welcome back, "+username+"!")
1459 else:
1460 username = get_new_username()
1461 print("we'll remeber you when you come back, "+username+"!")
1462 # 调用函数
1463 greet_user()
1464 get_stored_username()
1465 get_new_username()
1466
1467
1468 九、测试代码
1469
1470 # -*- coding: utf-8 -*-
1471 # 测试代码
1472
1473 # 测试函数
1474 # cat name_function.py
1475 def get_formatted_name(first,last):
1476 """generate a neatly formatted full name. """
1477 full_name = first+' '+last
1478 full_name = first+' '+middle+' '+last
1479 return full_name.title()
1480
1481 from name_function import get_formatted_name
1482 print("Enter 'q' at any time to quit.")
1483 while True:
1484 first = input("\nPlease give me a first name: ")
1485 if first == 'q':
1486 break
1487 last = input("Please give me a last name: ")
1488 if last == 'q':
1489 break
1490 formatted_name = get_formatted_name(first,last)
1491 print("\tNeatly formatted name: "+formatted_name+'.')
1492
1493
1494 # 单元测试和测试用例
1495
1496 # 可通过的测试例
1497
1498 # (先导入模块unittest以及要测试的函数,再创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。)
1499 import unittest
1500 from name_function import get_formatted_name
1501 class NamesTestCase(unittest.TestCase):
1502 """测试name_function.py"""
1503 def test_first_last_name(self):
1504 """能够正确的处理像Janis Joplin这样的姓名吗?"""
1505 # 使用实参'janis'和'joplin'调用get_formatted_name(),并将结果存储到变量formatted_name中
1506 formatted_name = get_formatted_name('zhang','shan')
1507 # 断言方法用来核实得到的结果是否与期望的结果一致,调用unittest的方法assertEqual(),向它传递formatted_name和'Janis Joplin'进行比较
1508 self.assertEqual(formatted_name,'Zhang Shan')
1509 # 代码行unittest.main()让Python运行这个文件中的测试
1510 unittest.main()
1511
1512 # 不能通过的测试例
1513
1514 #cat name_function.py
1515
1516 #def get_formatted_name(first,middle,last):
1517 # """生成整洁的姓名"""
1518 # full_name = first+' '+middle+' '+last
1519 # return full_name.title()
1520
1521 #cat test_name_function.py
1522 #import unittest
1523 #from name_function import get_formatted_name
1524 #class NamesTestCase(unittest.TestCase):
1525 # """测试name_function.py"""
1526 # def test_first_last_name(self):
1527 # """能够正确的处理像Janis Joplin这样的姓名吗?"""
1528 # formatted_name = get_formatted_name('zhang','shan')
1529 # self.assertEqual(formatted_name,'Zhang Shan')
1530 #unittest.main()
1531
1532 # 测试未通过怎么办
1533
1534 # 不修改测试,修改函数
1535
1536 #cat name_function.py
1537 #def get_formatted_name(first,last,middle=''):
1538 # """生成整洁的姓名"""
1539 # if middle:
1540 # full_name = first+' '+middle+' '+last
1541 # else:
1542 # full_name = first+' '+last
1543 # return full_name.title()
1544 # 测试代码不变
1545
1546
1547 # 添加新测试
1548
1549
1550 #import unittest
1551 #from name_function import get_formatted_name
1552 #class NameTestCase(unittest.TestCase):
1553 # """测试name_function.py"""
1554 # def test_first_last_name(self):
1555 # """能够正确的处理像zhang shan这样的姓名嘛?"""
1556 # formatted_name = get_formatted_name('zhang','shan')
1557 # self.assertEqual(formatted_name,'Zhang Shan')
1558 # def test_first_last_middle_name(self):
1559 # """能够正确的处理像zhang da shan这样的姓名嘛?"""
1560 # formatted_name = get_formatted_name('zhang','shan','da')
1561 # self.assertEqual(formatted_name,'Zhang Da Shan')
1562 #unittest.main()
1563
1564
1565 #------------ 测试的类 --------------
1566
1567 # 各种断言方法
1568 print("\n--------unittest Module中的断言方法-----------")
1569 unittest_moudle = {
1570 'assertEqual(a,b)':'核实a == b',
1571 'assertNotEqual(a,b)':'核实a != b',
1572 'assertTrue(x)':'核实x为True',
1573 'assertFalse(x)':'核实x为False',
1574 'assertIn(item,list)':'核实item在list中',
1575 'assertNotIn(item,list)':'核实item不在list中'
1576 }
1577 for way,mean in unittest_moudle.items():
1578 print("\n方法: "+way)
1579 print("含义: "+mean)
1580 print("\n\t\t"+way+" : "+mean)
1581
1582 # 一个要测试的类
1583 # cat nine.py
1584 class AnonymousSurvey():
1585 """收集匿名调查问卷的答案"""
1586 def __init__(self,question):
1587 """存储一个问题,并为存储答案做准备"""
1588 self.question = question
1589 self.responses = []
1590 def show_question(self):
1591 """显示调查问卷"""
1592 print(self.question)
1593 def store_response(self,new_response):
1594 """存储单份调查问卷"""
1595 self.responses.append(new_response)
1596 def show_results(self):
1597 """显示收集到的所有答案"""
1598 print("survey results:")
1599 for response in self.responses:
1600 print('- '+response)
1601
1602 from nine import AnonymousSurvey
1603 # 定义一个问题,并创建一个表示调查的AnonymousSurvey对象
1604 question = "what languages did you first learn to speak?"
1605 my_nine = AnonymousSurvey(question)
1606 # 显示问题并存储答案
1607 my_nine.show_question()
1608 print("enter 'q' at any time to quit.\n")
1609 while True:
1610 response = input("Language: ")
1611 if response == 'q':
1612 break
1613 my_nine.store_response(response)
1614 # 显示调查结果
1615 print("\nthank you to everyone who participated in the survey!")
1616 my_nine.show_results()
1617
1618 # 测试AnonymousSurvey类
1619 # 验证:如果用户面对调查问题时只提供了一个答案,这个答案也能被妥善地存储,存储后,使用方法assertIn()来核实它包含在答案列表中.
1620
1621 print("\n------------ 'assertIn'测试方法需python2.7及以上环境 -----------------")
1622
1623 print("\n=====测试只能测试第一个,之后所有代码忽略======")
1624 #cat test_nine.py
1625
1626 #import unittest
1627 #from nine import AnonymousSurvey
1628 #class TestAnonymousSurvey(unittest.TestCase):
1629 # """针对AnonymousSurvey类的测试"""
1630 # def test_store_single_response(self):
1631 # """测试单个答案会被妥善的存储"""
1632 # question = "what language did you first learn to speak?"
1633 # my_nine = AnonymousSurvey(question)
1634 # my_nine.store_response('English')
1635 # self.assertIn('English',my_nine.responses)
1636 # def test_store_three_responses(self):
1637 # """测试三个答案会被妥善地存储"""
1638 # question = "what language did you first learn to speak?"
1639 # my_nine = AnonymousSurvey(question)
1640 # responses = ['English','Chanise','Spanish']
1641 # for response in responses:
1642 # my_nine.store_response(response)
1643 # for response in responses:
1644 # self.assertIn(response,my_nine.responses)
1645 #unittest.main()
1646
1647 print("\n小结:注意 运行测试用例时,每完成一个单元测试,Python都打印一个字符:测试通过时打印一个句点;测试引发错误时打印一个E;测试导致断言失败时打印一个F。这就是你运行测试用例时,在输出的第一行中看到的句点和字符数量各不相同的原因。如果测试用例包含很多单元测试,需要运行很长时间,就可通过观察这些结果来获悉有多少个测试通过了。")
1648
1649 # 方法setUp()
1650
1651 # 优先运行方法setUp()
1652 import unittest
1653 from nine import AnonymousSurvey
1654 class TestAnonymousSurvey(unittest.TestCase):
1655 """针对AnonymousSurvey类的测试"""
1656 def setUp(self):
1657 """创建一个调查对象和一组答案,供使用的测试方法使用"""
1658 question = "what language did you first learn to speak?"
1659 self.my_nine = AnonymousSurvey(question)
1660 self.responses = ['english','chanise','spanish']
1661 def test_store_single_response(self):
1662 """测试单个答案会被妥善的存储"""
1663 self.my_nine.store_response(self.responses[0])
1664 self.assertIn(self.responses[0],self.my_nine.responses)
1665 def test_store_three_responses(self):
1666 """测试三个答案会被妥善地存储"""
1667 question = "what language did you first learn to speak?"
1668 my_nine = AnonymousSurvey(question)
1669 responses = ['English','Chanise','Spanish']
1670 for response in responses:
1671 my_nine.store_response(response)
1672 for response in responses:
1673 self.assertIn(response,my_nine.responses)
1674 unittest.main()