当前位置:   article > 正文

《Python编程:从入门到实践》 笔记(一)基础知识_python怎么换行输入另一条语句

python怎么换行输入另一条语句

 

目录

第02章 变量和简单数据类型

第03章 列表简介

第04章 操作列表

第05章 if语句

第06章 字典

第07章 用户输入和while循环

第08章 函数

第09章 类

第10章 文件和异常

第11章 测试代码


  • 如果你只求很简单的应用、如果你学过其他语言,那么看这一篇就已经可以做到使用Python 编程了。

 

第02章 变量和简单数据类型

1. 变量

  • 变量:我们添加了一个名为message 的变量 。每个变量都存储了一个值 :与变量相关联的信息。
    在程序中可随时修改变量的值,而Python将始终记录变量的最新值。
  1. message = "Hello Python world!"
  2. print(message)
  3. message = "Hello Python Crash Course world!"
  4. print(message)
  • 变量的命名和使用:

    ①变量名只能包含字母(最好用小写字母)、数字和下划线。变量名可以字母或下划线打头,但不能以数字打头,例如,可将变量命名为message_1,但不能将其命名为1_message。

    ②变量名不能包含空格,但可使用下划线来分隔其中的单词。例如,变量名greeting_message可行,但变量名greeting message会引发错误。

    ③不要将Python关键字和函数名用作变量名,即不要使用Python保留用于特殊用途的单词,如print。

    ④变量名应既简短又具有描述性。例如,name比n好,student_name比s_n好,name_length比length_of_persons_name好。

    ⑤慎用小写字母l和大写字母O,因为它们可能被人错看成数字1和0。

 

2. 字符串

  • 字符串:就是一系列字符。在Python中,用引号括起的都是字符串,其中的引号可以是单引号,也可以是双引号。这种灵活性让你能够在字符串中包含引号和撇号:
  1. 'I told my friend, "Python is my favorite language!"'
  2. "The language 'Python' is named after Monty Python, not the snake."
  3. "One of Python's strengths is its diverse and supportive community."
  • 使用方法修改字符串的大小写:
  1. name = "ada lovelace"
  2. print(name.title())
  3. #输出:Ada Lovelace
  • 方法title() 出现在这个变量的后面。方法 是Python可对数据执行的操作。
    在name.title() 中,name 后面的句点(. )让Python对变量name 执行方法title() 指定的操作。每个方法后面都跟着一对括号,这是因为方法通常需要额外的信息来完成其工作。这种信息是在括号内提供的。函数title() 不需要额外的信息,因此它后面的括号是空的。
  1. name = "Ada Lovelace"
  2. print(name.upper())
  3. print(name.lower())
  4. #输出:ADA LOVELACE
  5. # ada lovelace

 

  • 合并(拼接)字符串:
    Python使用加号(+ )来合并字符串。在这个示例中,我们使用+ 来合并first_name 、空格和last_name ,以得到完整的姓名,其结果如下:
  1. first_name = "ada"
  2. last_name = "lovelace"
  3. full_name = first_name + " " + last_name
  4. print(full_name)
  5. #输出:ada lovelace
  1. first_name = "ada"
  2. last_name = "lovelace"
  3. full_name = first_name + " " + last_name
  4. print("Hello, " + full_name.title() + "!")
  5. #输出:Hello, Ada Lovelace!

 

  • python字符串中,同样可以用\t 和 \n等制表符。
  • 删除字符串末尾多余的空白:
    1. ① >>> favorite_language = 'python '
    2. ② >>> favorite_language
    3. 'python '
    4. ③ >>> favorite_language.rstrip()
    5. 'python'
    6. ④ >>> favorite_language
    7. 'python '
    存储在变量favorite_language 中的字符串末尾包含多余的空白(见①)。你在终端会话中向Python询问这个变量的值时,可看到末尾的空格(见②)。对变
    量favorite_language 调用方法rstrip() 后(见③),这个多余的空格被删除了。然而,这种删除只是暂时的,接下来再次询问favorite_language 的值时,你会发
    现这个字符串与输入时一样,依然包含多余的空白(见④)。
    要永久删除这个字符串中的空白,必须将删除操作的结果存回到变量中:
    1. favorite_language = 'python '
    2. favorite_language = favorite_language.rstrip()
  • 你还可以剔除字符串开头的空白:可使用方法 lstrip()

 

3. 数字

①整数

  • 在Python中,可对整数执行加(+ )减(- )乘(* )除(/ )求模(%)运算:

  1. >>> 2 + 3
  2. 5 >>> 3
  3. -
  4. 2
  5. 1 >>> 2
  6. *
  7. 3
  8. 6 >>> 3
  9. /
  10. 2
  11. 1.5
  • Python使用两个乘号表示乘方运算
  1. >>> 3 ** 2
  2. 9
  3. >>> 3 ** 3
  4. 27
  5. >>> 10 ** 6
  6. 1000000
  • Python还支持运算次序,因此你可在同一个表达式中使用多种运算。你还可以使用括号来修改运算次序,让Python按你指定的次序执行运算,如下所示:
  1. >>> 2 + 3*4
  2. 14
  3. >>> (2 + 3) * 4
  4. 20
  • 空格不影响Python计算表达式的方式,它们的存在旨在让你阅读代码时,能迅速确定先执行哪些运算。

②浮点数

  • 从很大程度上说,使用浮点数时都无需考虑其行为。你只需输入要使用的数字,Python通常都会按你期望的方式处理它们。但需要注意的是,结果包含的小数位数可能是不确定的:
  1. >>> 0.2 + 0.1
  2. 0.30000000000000004
  3. >>> 3 * 0.1
  4. 0.30000000000000004
  • 错误的代码,因为:Python发现你使用了一个值为整数(int )的变量,但它不知道该如何解读这个值。Python知道,这个变量表示的可能是数值23,也可能是字符2和3。像上面这样在字符串中使用整数时,需要显式地指出你希望Python将这个整数用作字符串。
     
    1. age = 23
    2. message = "Happy " + age + "rd Birthday!"
    3. print(message)
    为此,可调用函数str() ,它让Python将非字符串值表示为字符串
    1. age = 23
    2. message = "Happy " + str(age) + "rd Birthday!"
    3. print(message)

     

4.注释

  • 在Python中,注释用井号(# )标识。井号后面的内容都会被Python解释器忽略。

 

第03章 列表简介

1. 列表

  • 列表让你能够在一个地方存储成组的信息,其中可以只包含几个元素,也可以包含数百万个元素。列表是新手可直接使用的最强大的Python功能之一,它融合了众多重要的编程概念。
  • 列表:由一系列按特定顺序排列的元素组成。你可以创建包含字母表中所有字母、数字0~9或所有家庭成员姓名的列表;也可以将任何东西加入列表中,其中的元素之间可以没有任何关系。

 

  • 在Python中,用方括号([] )来表示列表,并用逗号来分隔其中的元素:
  1. bicycles = ['trek', 'cannondale', 'redline', 'specialized']
  2. print(bicycles)
  3. #输出:
  4. #['trek', 'cannondale', 'redline', 'specialized']
  • 访问列表元素,下面的代码从列表bicycles 中提取第一款自行车(你还可以对任何列表元素调用第2章介绍的字符串方法):
  1. bicycles = ['trek', 'cannondale', 'redline', 'specialized']
  2. print(bicycles[0])
  3. #输出:trek
  • Python为访问最后一个列表元素提供了一种特殊语法。通过将索引指定为-1 ,可让Python返回最后一个列表元素:
  1. bicycles = ['trek', 'cannondale', 'redline', 'specialized']
  2. print(bicycles[-1])
  3. #输出:specialized

2. 修改、添加和删除元素

  • 修改元素
  1. motorcycles = ['honda', 'yamaha', 'suzuki']
  2. print(motorcycles)
  3. motorcycles[0] = 'ducati'
  4. print(motorcycles)
  • 给列表附加元素时,它将添加到列表末尾。继续使用前一个示例中的列表,在其末尾添加新元素'ducati' :
  1. motorcycles = ['honda', 'yamaha', 'suzuki']
  2. print(motorcycles)
  3. motorcycles.append('ducati')
  4. print(motorcycles)
  5. #输出:
  6. #['honda', 'yamaha', 'suzuki']
  7. #['honda', 'yamaha', 'suzuki', 'ducati']
  • 你可以先创建一个空列表,再使用一系列的append() 语句添加元素。
  1. motorcycles = []
  2. motorcycles.append('honda')
  3. motorcycles.append('yamaha')
  4. motorcycles.append('suzuki')
  5. print(motorcycles)
  • 使用方法insert() 可在列表的任何位置添加新元素。这种操作将插入位置及其后面的每个元素都右移一个位置:
  1. motorcycles = ['honda', 'yamaha', 'suzuki']
  2. motorcycles.insert(0, 'ducati')
  3. print(motorcycles)
  • 如果知道要删除的元素在列表中的位置,可使用del 语句:
  1. motorcycles = ['honda', 'yamaha', 'suzuki']
  2. print(motorcycles)
  3. del motorcycles[1]
  4. print(motorcycles)
  • 方法pop() 可删除列表末尾的元素,并让你能够接着使用它:
  1. motorcycles = ['honda', 'yamaha', 'suzuki']
  2. print(motorcycles)
  3. popped_motorcycle = motorcycles.pop()
  4. print(motorcycles)
  5. print(popped_motorcycle)
  6. #输出:
  7. #['honda', 'yamaha', 'suzuki']
  8. #['honda', 'yamaha']
  9. #suzuki
  • 实际上,你可以使用pop() 来删除列表中任何位置的元素,只需在括号中指定要删除的元素的索引即可:
  1. motorcycles = ['honda', 'yamaha', 'suzuki']
  2. first_owned = motorcycles.pop(0)
  3. print('The first motorcycle I owned was a ' + first_owned.title() + '.')
  • 有时候,你不知道要从列表中删除的值所处的位置。如果你只知道要删除的元素的值,可使用方法remove() :
  1. motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']
  2. print(motorcycles)
  3. too_expensive = 'ducati'
  4. motorcycles.remove(too_expensive)
  5. print(motorcycles)
  6. print("\nA " + too_expensive.title() + " is too expensive for me.")

3. 组织列表

  • Python方法sort() 让你能够较为轻松地对列表进行排序:
  1. cars = ['bmw', 'audi', 'toyota', 'subaru']
  2. cars.sort()
  3. print(cars)
  4. #输出:
  5. #['audi', 'bmw', 'subaru', 'toyota']
  • 你还可以按与字母顺序相反的顺序排列列表元素,为此,只需向sort() 方法传递参数reverse=True:
  1. cars = ['bmw', 'audi', 'toyota', 'subaru']
  2. cars.sort(reverse=True)
  3. print(cars)
  • 要保留列表元素原来的排列顺序,同时以特定的顺序呈现它们,可使用函数sorted() 。函数sorted() 让你能够按特定顺序显示列表元素,同时不影响它们在列表中的原始排列顺序:
  1. cars = ['bmw', 'audi', 'toyota', 'subaru']
  2. print("Here is the original list:")
  3. print(cars)
  4. print("\nHere is the sorted list:")
  5. print(sorted(cars))
  6. print("\nHere is the original list again:")
  7. print(cars)
  • 要反转列表元素的排列顺序,可使用方法reverse() :
  1. cars = ['bmw', 'audi', 'toyota', 'subaru']
  2. print(cars)
  3. cars.reverse()
  4. print(cars)
  • 使用函数len() 可快速获悉列表的长度:
  1. cars = ['bmw', 'audi', 'toyota', 'subaru']
  2. print(len(cars))

 

第04章 操作列表

1. 遍历整个列表

  • for循环遍历:
  1. magicians = ['alice', 'david', 'carolina']
  2. for magician in magicians:
  3. print(magician)
  • 在for 循环中,想包含多少行代码都可以。在代码行for magician in magicians 后面,每个缩进的代码行都是循环的一部分,且将针对列表中的每个值都执行一次。因此,可对列表中的每个值执行任意次数的操作:
  1. magicians = ['alice', 'david', 'carolina']
  2. for magician in magicians:
  3. print(magician.title() + ", that was a great trick!")
  4. print("I can't wait to see your next trick, " + magician.title() + ".\n")
  • for 语句末尾的冒号告诉Python,下一行是循环的第一行。如果你不小心遗漏了冒号,将导致语法错误,因为Python不知道你意欲何为。

2.创建数值列表

  • Python函数range() 让你能够轻松地生成一系列的数字。range() 只是打印数字1~4,这是你在编程语言中经常看到的差一行为的结果。函数range() 让Python从你指定的第一个值开始数,并在到达你指定的第二个值后停止,因此输出不包含第二个值(这里为5):
  1. for value in range(1,5):
  2. print(value)
  3. #输出:
  4. #1
  5. #2
  6. #3
  7. #4
  • 要创建数字列表,可使用函数list() 将range() 的结果直接转换为列表。如果将range() 作为list() 的参数,输出将为一个数字列表:
  1. numbers = list(range(1,6))
  2. print(numbers)
  • 使用函数range() 时,还可指定步长。例如,下面的代码打印1~10内的偶数:
  1. even_numbers = list(range(2,11,2))
  2. print(even_numbers)
  • 使用函数range() 几乎能够创建任何需要的数字集,例如,如何创建一个列表,其中包含前10个整数(即1~10)的平方呢?在Python中,两个星号(** )表示乘方运算。下面的代码演示了如何将前10个整数的平方加入到一个列表中:
  1. squares = []
  2. for value in range(1,11):
  3. square = value**2
  4. squares.append(square)
  5. print(squares)
  • 有几个专门用于处理数字列表的Python函数。例如,你可以轻松地找出数字列表的最大值、最小值和总和:
  1. digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
  2. print(min(digits))
  3. print(max(digits))
  4. print(sum(digits))

 

  • 列表解析:将for 循环和创建新元素的代码合并成一行,并自动附加新元素。
  • 要使用这种语法,首先指定一个描述性的列表名,如squares ;然后,指定一个左方括号,并定义一个表达式,用于生成你要存储到列表中的值。
    在这个示例中,表达式为value**2 ,它计算平方值。接下来,编写一个for 循环,用于给表达式提供值,再加上右方括号。在这个示例中,for 循环为for value in range(1,11) ,它将值1~10提供给表达式value**2 。请注意,这里的for 语句末尾没有冒号。
  1. squares = [value**2 for value in range(1,11)]
  2. print(squares)

3. 使用列表的一部分

  • 你可以处理列表的部分元素——Python称之为切片
  • 要创建切片,可指定要使用的第一个元素和最后一个元素的索引。与函数range() 一样,Python在到达你指定的第二个索引前面的元素后停止。要输出列表中的前三个元素,需要指定索引0~3,这将输出分别为0 、1 和2 的元素:
  1. players = ['charles', 'martina', 'michael', 'florence', 'eli']
  2. print(players[0:3])
  3. #输出:['charles', 'martina', 'michael']
  • 如果你没有指定第一个索引,Python将自动从列表开头开始。要让切片终止于列表末尾,也可使用类似的语法。
  1. #自动从头开始
  2. players = ['charles', 'martina', 'michael', 'florence', 'eli']
  3. print(players[:4])
  4. #自动到尾部结束
  5. players = ['charles', 'martina', 'michael', 'florence', 'eli']
  6. print(players[2:])
  • 负数索引返回离列表末尾相应距离的元素,因此你可以输出列表末尾的任何切片。
    例如,如果你要输出名单上的最后三名队员,可使用切片players[-3:] :
  1. players = ['charles', 'martina', 'michael', 'florence', 'eli']
  2. print(players[-3:])

 

  • 如果要遍历列表的部分元素,可在for 循环中使用切片:
  1. players = ['charles', 'martina', 'michael', 'florence', 'eli']
  2. print("Here are the first three players on my team:")
  3. for player in players[:3]:
  4. print(player.title())
  • 通过切片复制一个列表(会有两个列表):
  1. my_foods = ['pizza', 'falafel', 'carrot cake']
  2. #会有两个不同的列表存在
  3. friend_foods = my_foods[:]
  4. my_foods.append('cannoli')
  5. friend_foods.append('ice cream')
  • 而下面这个例子将my_foods 赋给friend_foods ,而不是将my_foods 的副本存储到friend_foods 。这种语法实际上是让Python将新变量friend_foods 关联到包含在my_foods 中的列表,因此这两个变量都指向同一个列表
  1. my_foods = ['pizza', 'falafel', 'carrot cake']
  2. #这行不通
  3. friend_foods = my_foods
  4. my_foods.append('cannoli')
  5. friend_foods.append('ice cream')

4.元组

  • 有时候你需要创建一系列不可修改的元素,元组可以满足这种需求。Python将不能修改的值称为不可变的 ,而不可变的列表被称为元组
  • 元组看起来犹如列表,但使用圆括号而不是方括号来标识。定义元组后,就可以使用索引来访问其元素,就像访问列表元素一样。
  1. dimensions = (200, 50)
  2. print(dimensions[0])
  3. print(dimensions[1])
  • 像列表一样,也可以使用for 循环来遍历元组中的所有值。
  • 虽然不能修改元组的元素,但可以给存储元组的变量赋值。因此,如果要修改前述矩形的尺寸,可重新定义整个元组:
  1. dimensions = (200, 50)
  2. print("Original dimensions:")
  3. for dimension in dimensions:
  4. print(dimension)
  5. dimensions = (400, 100)
  6. print("\nModified dimensions:")
  7. for dimension in dimensions:
  8. print(dimension)

5. 代码格式

  • Python改进提案 (Python Enhancement Proposal,PEP):PEP 8是最古老的PEP之一,它向Python程序员提供了代码格式设置指南。PEP 8的篇幅很长,但大都与复杂的编码结构相关。

 

  • PEP 8建议每级缩进都使用四个空格,这既可提高可读性,又留下了足够的多级缩进空间。
  • 你在编写代码时应该使用制表符键,但一定要对编辑器进行设置,使其在文档中插入空格而不是制表符。在程序中混合使用制表符和空格可能导致极难解决的问题。

 

  • 很多Python程序员都建议每行不超过80字符。
  • PEP 8还建议注释的行长都不超过72字符,因为有些工具为大型项目自动生成文档时,会在每行注释开头添加格式化字符。

 

第05章 if语句

1. 条件测试

  • 这个示例中的循环首先检查当前的汽车名是否是'bmw' 。如果是,就以全大写的方式打印它;否则就以首字母大写的方式打印:
  1. cars = ['audi', 'bmw', 'subaru', 'toyota']
  2. for car in cars:
  3. if car == 'bmw':
  4. print(car.upper())
  5. else:
  6. print(car.title())
  • 在Python中检查是否相等时区分大小写,例如,两个大小写不同的值会被视为不相等:
  1. car = 'Audi'
  2. car == 'audi' #False
  • 如果大小写无关紧要,而只想检查变量的值,可将变量的值转换为小写,再进行比较:
  1. car = 'Audi'
  2. car.lower() == 'audi' #True
  • 要判断两个值是否不等,可结合使用惊叹号和等号(!= ),其中的惊叹号表示不 ,在很多编程语言中都如此。
  • python中可以使用==、<、>、<=、>=来进行数值比较。
  • PEP 8提供的建议是,在诸如== 、>= 和<= 等比较运算符两边各添加一个空格。

 

  • 可以用and和or来检查多个条件:
  1. age_0 = 22
  2. age_1 = 18
  3. age_0 >= 21 and age_1 >= 21 #False
  1. age_0 = 22
  2. age_1 = 18
  3. age_0 >= 21 or age_1 >= 21 #True

 

  • 还有些时候,确定特定的值未包含在列表中很重要;在这种情况下,可使用关键字not in 。例如,如果有一个列表,其中包含被禁止在论坛上发表评论的用户,就可在允许用户提交评论前检查他是否被禁言:
  1. banned_users = ['andrew', 'carolina', 'david']
  2. user = 'marie'
  3. if user not in banned_users:
  4. print(user.title() + ", you can post a response if you wish.")
  • 布尔表达式
  1. game_active = True
  2. can_edit = False

2. if语句

  • 最简单的if 语句只有一个测试和一个操作。在紧跟在if 语句后面的代码块中,可根据需要包含任意数量的代码行。
  1. if conditional_test:
  2. do something
  • 经常需要在条件测试通过了时执行一个操作,并在没有通过时执行另一个操作;在这种情况下,可使用Python提供的if-else 语句。
  1. age = 17
  2. if age >= 18:
  3. print("You are old enough to vote!")
  4. print("Have you registered to vote yet?")
  5. else:
  6. print("Sorry, you are too young to vote.")
  7. print("Please register to vote as soon as you turn 18!")
  • 经常需要检查超过两个的情形,为此可使用Python提供的if-elif-else 结构。Python只执行if-elif-else 结构中的一个代码块。
  1. age = 12
  2. if age < 4:
  3. print("Your admission cost is $0.")
  4. elif age < 18:
  5. print("Your admission cost is $5.")
  6. else:
  7. print("Your admission cost is $10.")

 

  • 可根据需要使用任意数量的elif 代码块。
  • Python并不要求if-elif 结构后面必须有else 代码块。

 

3. 使用if语句处理列表

  • 通过结合使用if 语句和列表,可完成一些有趣的任务:对列表中特定的值做特殊处理;高效地管理不断变化的情形,如餐馆是否还有特定的食材;证明代码在各种情形下都将按预期那样运行。

 

  • 比萨店在制作比萨时,每添加一种配料都打印一条消息。通过创建一个列表,在其中包含顾客点的配料,并使用一个循环来指出添加到比萨中的配料。然而,如果比萨店的青椒用完了,该如何处理呢?为妥善地处理这种情况,可在for 循环中包含一条if 语句:
  1. requested_toppings = ['mushrooms', 'green peppers', 'extra cheese']
  2. for requested_topping in requested_toppings:
  3. if requested_topping == 'green peppers':
  4. print("Sorry, we are out of green peppers right now.")
  5. else:
  6. print("Adding " + requested_topping + ".")
  7. print("\nFinished making your pizza!")

 

  • 预先确定列表不是空的
  1. requested_toppings = []
  2. if requested_toppings:
  3. for requested_topping in requested_toppings:
  4. print("Adding " + requested_topping + ".")
  5. print("\nFinished making your pizza!")
  6. else:
  7. print("Are you sure you want a plain pizza?")
  • 使用多个列表
  1. available_toppings = ['mushrooms', 'olives', 'green peppers',
  2. 'pepperoni', 'pineapple', 'extra cheese']
  3. requested_toppings = ['mushrooms', 'french fries', 'extra cheese']
  4. for requested_topping in requested_toppings:
  5. if requested_topping in available_toppings:
  6. print("Adding " + requested_topping + ".")
  7. else:
  8. print("Sorry, we don't have " + requested_topping + ".")
  9. print("\nFinished making your pizza!")

 

第06章 字典

1. 使用字典

  • 在Python中,字典:是一系列 键 - 值对 。每个键都与一个值相关联,你可以使用键来访问与之相关联的值。
  • 键 - 值对:两个相关联的值。指定键时,Python将返回与之相关联的值。
  • 值:可以是数字、字符串、列表乃至字典。事实上,可将任何Python对象用作字典中的值。
  • 在Python中,字典用放在花括号{} 中的一系列 键 - 值对 表示。键和值之间用冒号分隔,而键 - 值对之间用逗号分隔。
  • 在字典中,你想存储多少个键—值对都可以。最简单的字典只有一个键—值对

 

  • 要获取与键相关联的值,可依次指定字典名和放在方括号内的键。
  1. alien_0 = {'color': 'green', 'points': 5}
  2. print(alien_0['color'])
  3. print(alien_0['points'])
  4. #输出:
  5. #green
  6. #5
  • 要添加键—值对,可依次指定字典名、用方括号括起的键和相关联的值。
  1. alien_0 = {'color': 'green', 'points': 5}
  2. print(alien_0)
  3. alien_0['x_position'] = 0
  4. alien_0['y_position'] = 25
  5. print(alien_0)
  6. #输出:
  7. #{'color': 'green', 'points': 5}
  8. #{'color': 'green', 'points': 5, 'y_position': 25, 'x_position': 0}
  • 要修改字典中的值,可依次指定字典名、用方括号括起的键以及与该键相关联的新值。
  1. alien_0 = {'color': 'green'}
  2. alien_0['color'] = 'yellow'
  • 对于字典中不再需要的信息,可使用del 语句将相应的键-值对彻底删除。使用del 语句时,必须指定字典名和要删除的键。删除的键-值对永远消失了
  1. alien_0 = {'color': 'green', 'points': 5}
  2. del alien_0['points']

 

  • 你也可以使用字典来存储众多对象的同一种信息。我们将一个较大的字典放在了多行中。
  • 确定需要使用多行来定义字典时,在输入左花括号后按回车键,再在下一行缩进四个空格,指定第一个键-值对,并在它后面加上一个逗号。此后你再次按回车键时,文本编辑器将自动缩进后续键-值对,且缩进量与第一个键-值对相同。
  • 定义好字典后,在最后一个键-值对的下一行添加一个右花括号,并缩进四个空格,使其与字典中的键对齐。另外一种不错的做法是在最后一个键-值对后面也加上逗号,为以后在下一行添加键-值对做好准备。
  1. favorite_languages = {
  2. 'jen': 'python',
  3. 'sarah': 'c',
  4. 'edward': 'ruby',
  5. 'phil': 'python',
  6. }

2. 遍历字典

  • 字典可用于以各种方式存储信息,因此有多种遍历字典的方式:可遍历字典的所有键—值对、键或值。
  • 要编写用于遍历字典的for 循环,可声明两个变量,用于存储键—值对中的键和值。对于这两个变量,可使用任何名称。for 语句的第二部分包含字典名和方法items() ,它返回一个键—值对列表。
  1. user_0 = {
  2. 'username': 'efermi',
  3. 'first': 'enrico',
  4. 'last': 'fermi',
  5. }
  6. for key, value in user_0.items():
  7. print("\nKey: " + key)
  8. print("Value: " + value)
  • 即便遍历字典时,键-值对 的返回顺序也与存储顺序不同。Python不关心键—值对的存储顺序,而只跟踪键和值之间的关联关系。

 

  • 遍历字典中的所有键:在不需要使用字典中的值时,方法keys() 很有用。
  1. favorite_languages = {
  2. 'jen': 'python',
  3. 'sarah': 'c',
  4. 'edward': 'ruby',
  5. 'phil': 'python',
  6. }
  7. for name in favorite_languages.keys():
  8. print(name.title())
  • 遍历字典时,会默认遍历所有的键,因此,如果将上述代码中的for name in favorite_languages.keys(): 替换为for name in favorite_languages: ,输出将不变。
  • 按顺序遍历字典中的所有键,可使用函数sorted() 来获得按特定顺序排列的键列表的副本:
  1. favorite_languages = {
  2. 'jen': 'python',
  3. 'sarah': 'c',
  4. 'edward': 'ruby',
  5. 'phil': 'python',
  6. }
  7. for name in sorted(favorite_languages.keys()):
  8. print(name.title() + ", thank you for taking the poll.")

 

  • 遍历字典中的所有值:如果你感兴趣的主要是字典包含的值,可使用方法values() ,它返回一个值列表,而不包含任何键。
  • 为剔除重复项,可使用集合(set)。集合:类似于列表,但每个元素都必须是独一无二的:
  1. favorite_languages = {
  2. 'jen': 'python',
  3. 'sarah': 'c',
  4. 'edward': 'ruby',
  5. 'phil': 'python',
  6. }
  7. print("The following languages have been mentioned:")
  8. for language in set(favorite_languages.values()):
  9. print(language.title())

 

3.嵌套

  • 有时候,需要将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套 。你可以在列表中嵌套字典、在字典中嵌套列表甚至在字典中嵌套字典

 

  • 列表中嵌套字典
  1. alien_0 = {'color': 'green', 'points': 5}
  2. alien_1 = {'color': 'yellow', 'points': 10}
  3. alien_2 = {'color': 'red', 'points': 15}
  4. aliens = [alien_0, alien_1, alien_2]
  5. for alien in aliens:
  6. print(alien)
  1. # 创建一个用于存储外星人的空列表
  2. aliens = []
  3. # 创建30个绿色的外星人
  4. for alien_number in range(30):
  5. new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
  6. aliens.append(new_alien)
  7. # 显示前五个外星人
  8. for alien in aliens[:5]:
  9. print(alien)
  10. print("...")
  11. # 显示创建了多少个外星人
  12. print("Total number of aliens: " + str(len(aliens)))

 

  • 字典中嵌套列表
  1. favorite_languages = {
  2. 'jen': ['python', 'ruby'],
  3. 'sarah': ['c'],
  4. 'edward': ['ruby', 'go'],
  5. 'phil': ['python', 'haskell'],
  6. }
  7. for name, languages in favorite_languages.items():
  8. print("\n" + name.title() + "'s favorite languages are:")
  9. for language in languages:
  10. print("\t" + language.title())

 

  • 字典中嵌套字典:下面例子是有多个网站用户,每个都有独特的用户名,可在字典中将用户名作为键,然后将每位用户的信息存储在
    一个字典中,并将该字典作为与用户名相关联的值。在下面的程序中,对于每位用户,我们都存储了其三项信息:名、姓和居住地;为访问这些信息,我们遍历所有的用户名,并访问与每个用户名相关联的信息字典
  1. users = {
  2. 'aeinstein': {
  3. 'first': 'albert',
  4. 'last': 'einstein',
  5. 'location': 'princeton',
  6. },
  7. 'mcurie': {
  8. 'first': 'marie',
  9. 'last': 'curie',
  10. 'location': 'paris',
  11. },
  12. }
  13. for username, user_info in users.items():
  14. print("\nUsername: " + username)
  15. full_name = user_info['first'] + " " + user_info['last']
  16. location = user_info['location']
  17. print("\tFull name: " + full_name.title())
  18. print("\tLocation: " + location.title())
  • 可在字典中嵌套字典,但这样做时,代码可能很快复杂起来。

 

第07章 用户输入和while循环

1. 函数input() 的工作原理

  • 函数input() 让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python将其存储在一个变量中,以方便你使用。
  1. message = input("Tell me something, and I will repeat it back to you: ")
  2. print(message)
  • 使用函数input() 时,Python将用户输入解读为字符串。
  1. age = input("How old are you? ") #21
  2. age
  3. #输出:'21'
  • 可使用函数int() ,它让Python将输入转换为数值
  1. height = input("How tall are you, in inches? ")
  2. height = int(height)
  3. if height >= 36:
  4. print("\nYou're tall enough to ride!")
  5. else:
  6. print("\nYou'll be able to ride when you're a little older.")

2. while循环

  • 你可以使用while 循环来数数,例如,下面的while 循环从1数到5:
  1. current_number = 1
  2. while current_number <= 5:
  3. print(current_number)
  4. current_number += 1
  • 可使用while 循环让程序在用户愿意时不断地运行。我们在其中定义了一个退出值,只要用户输入的不是这个值,程序就接着运行:
  1. prompt = "\nTell me something, and I will repeat it back to you:"
  2. prompt += "\nEnter 'quit' to end the program. "
  3. message = ""
  4. while message != 'quit':
  5. message = input(prompt)
  6. print(message)

 

  • 要立即退出while 循环,不再运行循环中余下的代码,也不管条件测试的结果如何,可使用break 语句
  1. prompt = "\nPlease enter the name of a city you have visited:"
  2. prompt += "\n(Enter 'quit' when you are finished.) "
  3. while True:
  4. city = input(prompt)
  5. if city == 'quit':
  6. break
  7. else:
  8. print("I'd love to go to " + city.title() + "!")
  • 要返回到循环开头,并根据条件测试结果决定是否继续执行循环,可使用continue 语句,它不像break 语句那样不再执行余下的代码并退出整个循环。
  1. current_number = 0
  2. while current_number < 10:
  3. current_number += 1
  4. if current_number % 2 == 0:
  5. continue
  6. print(current_number)

 

3. 使用while 循环来处理列表和字典

  • for 循环是一种遍历列表的有效方式,但在for 循环中不应修改列表,否则将导致Python难以跟踪其中的元素。要在遍历列表的同时对其进行修改,可使用while 循环。通过将while 循环同列表和字典结合起来使用,可收集、存储并组织大量输入,供以后查看和显示。
  • 假设有一个列表,其中包含新注册但还未验证的网站用户;验证这些用户后,如何将他们移到另一个已验证用户列表中呢?
  1. # 首先,创建一个待验证用户列表
  2. # 和一个用于存储已验证用户的空列表
  3. unconfirmed_users = ['alice', 'brian', 'candace']
  4. confirmed_users = []
  5. # 验证每个用户,直到没有未验证用户为止
  6. # 将每个经过验证的列表都移到已验证用户列表中
  7. while unconfirmed_users:
  8. current_user = unconfirmed_users.pop()
  9. print("Verifying user: " + current_user.title())
  10. confirmed_users.append(current_user)
  11. # 显示所有已验证的用户
  12. print("\nThe following users have been confirmed:")
  13. for confirmed_user in confirmed_users:
  14. print(confirmed_user.title())
  • 可使用while循环提示用户输入任意数量的信息。下面来创建一个调查程序,其中的循环每次执行时都提示输入被调查者的名字和回答。我们将收集的数据存储在一个字典中,以便将回答同被调查者关联起来:
  1. responses = {}
  2. # 设置一个标志,指出调查是否继续
  3. polling_active = True
  4. while polling_active:
  5. # 提示输入被调查者的名字和回答
  6. name = input("\nWhat is your name? ")
  7. response = input("Which mountain would you like to climb someday? ")
  8. # 将答卷存储在字典中
  9. responses[name] = response
  10. # 看看是否还有人要参与调查
  11. repeat = input("Would you like to let another person respond? (yes/ no) ")
  12. if repeat == 'no':
  13. polling_active = False
  14. # 调查结束,显示结果
  15. print("\n--- Poll Results ---")
  16. for name, response in responses.items():
  17. print(name + " would like to climb " + response + ".")

 

第08章 函数

1. 定义函数

  • 使用关键字def 来告诉Python你要定义一个函数。这是函数定义 ,向Python指出了函数名,还可能在括号内指出函数为完成其任务需要什么样的信息。定义以冒号结尾。
  • 紧跟在def greet_user(): 后面的所有缩进行构成了函数体。三引号文本是被称为文档字符串 (docstring)的注释,描述了函数是做什么的。文档字符串用三引号括起,Python使用它们来生成有关程序中函数的文档。
  1. def greet_user():
  2. """显示简单的问候语"""
  3. print("Hello!")
  4. greet_user()
  • 向函数传递信息
  1. def greet_user(username):
  2. """显示简单的问候语"""
  3. print("Hello, " + username.title() + "!")
  4. greet_user('jesse')

2. 传递实参

  • 鉴于函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。向函数传递实参的方式很多,可使用位置实参 ,这要求实参的顺序与形参的顺序相同;也可使用关键字实参 ,其中每个实参都由变量名和值组成;还可使用列表和字典。

 

  • 你调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参 。(和其他语言的函数调用类似)

 

  • 关键字实参:是传递给函数的 名称-值对。你直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆(不会得到名为Hamster的harry这样的结果)。关键字实参让你无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。
  1. def describe_pet(animal_type, pet_name):
  2. """显示宠物的信息"""
  3. print("\nI have a " + animal_type + ".")
  4. print("My " + animal_type + "'s name is " + pet_name.title() + ".")
  5. describe_pet(animal_type='hamster', pet_name='harry')

 

  • 编写函数时,可给每个形参指定默认值 。在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。因此,给形参指定默认值后,可在函数调用中省略相应的实参。使用默认值可简化函数调用,还可清楚地指出函数的典型用法。
  1. def describe_pet(pet_name, animal_type='dog'):
  2. """显示宠物的信息"""
  3. print("\nI have a " + animal_type + ".")
  4. print("My " + animal_type + "'s name is " + pet_name.title() + ".")
  5. describe_pet(pet_name='willie')
  6. #输出:
  7. #I have a dog.
  8. #My dog's name is Willie.
  • 由于给animal_type 指定了默认值,无需通过实参来指定动物类型,因此在函数调用中只包含一个实参——宠物的名字。然而,Python依然将这个实参视为位置实参,因此如果函数调用中只包含宠物的名字,这个实参将关联到函数定义中的第一个形参。这就是需要将pet_name 放在形参列表开头的原因所在。因此可以这样调用:describe_pet('willie')
  • 有时候,需要让实参变成可选的,这样使用函数的人就只需在必要时才提供额外的信息。可使用默认值来让实参变成可选的。

 

3. 返回值

  • 函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值。函数返回的值被称为返回值
  • 在函数中,可使用return 语句将值返回到调用函数的代码行。返回值让你能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序。

 

  • 返回简单值:
  1. def get_formatted_name(first_name, last_name):
  2. """返回整洁的姓名"""
  3. full_name = first_name + ' ' + last_name
  4. return full_name.title()
  5. musician = get_formatted_name('jimi', 'hendrix')
  6. print(musician)
  • 返回字典:
  1. def build_person(first_name, last_name):
  2. """返回一个字典,其中包含有关一个人的信息"""
  3. person = {'first': first_name, 'last': last_name}
  4. return person
  5. musician = build_person('jimi', 'hendrix')
  6. print(musician)

 

4. 传递列表

  • 你经常会发现,向函数传递列表很有用,这种列表包含的可能是名字、数字或更复杂的对象(如字典)。将列表传递给函数后,函数就能直接访问其内容。下面使用函数来提高处理列表的效率。
  • 将列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永久性的,这让你能够高效地处理大量的数据。
  1. def print_models(unprinted_designs, completed_models):
  2. """
  3. 模拟打印每个设计,直到没有未打印的设计为止
  4. 打印每个设计后,都将其移到列表completed_models中
  5. """
  6. while unprinted_designs:
  7. current_design = unprinted_designs.pop()
  8. # 模拟根据设计制作3D打印模型的过程
  9. print("Printing model: " + current_design)
  10. completed_models.append(current_design)
  11. def show_completed_models(completed_models):
  12. """显示打印好的所有模型"""
  13. print("\nThe following models have been printed:")
  14. for completed_model in completed_models:
  15. print(completed_model)
  16. #函数调用
  17. unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
  18. completed_models = []
  19. print_models(unprinted_designs, completed_models)
  20. show_completed_models(completed_models)

 

  • 有时候,需要禁止函数修改列表。可向函数传递列表的副本而不是原件;这样函数所做的任何修改都只影响副本,而丝毫不影响原件: function_name(list_name[:])

 

5. 传递任意数量的实参

  • 有时候,你预先不知道函数需要接受多少个实参,好在Python允许函数从调用语句中收集任意数量的实参。
  • 形参名*toppings 中的星号让Python创建一个名为toppings 的空元组,并将收到的所有值都封装到这个元组中。注意,Python将实参封装到一个元组中,即便函数只收到一个值也如此。
  • 下面的函数只有一个形参*toppings ,但不管调用语句提供了多少实参,这个形参都将它们统统收入囊中:
  1. def make_pizza(*toppings):
  2. """概述要制作的比萨"""
  3. print("\nMaking a pizza with the following toppings:")
  4. for topping in toppings:
  5. print("- " + topping)
  6. make_pizza('pepperoni')
  7. make_pizza('mushrooms', 'green peppers', 'extra cheese')
  8. #输出:
  9. #Making a pizza with the following toppings:
  10. #- pepperoni
  11. #Making a pizza with the following toppings:
  12. #- mushrooms
  13. #- green peppers
  14. #- extra cheese

 

  • 如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
  1. def make_pizza(size, *toppings):
  2. """概述要制作的比萨"""
  3. print("\nMaking a " + str(size) +
  4. "-inch pizza with the following toppings:")
  5. for topping in toppings:
  6. print("- " + topping)
  7. make_pizza(16, 'pepperoni')
  8. make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

 

  • 使用任意数量的关键字实参:有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的 键-值对 ——调用语句提供了多少就接受多少。
  1. def build_profile(first, last, **user_info):
  2. """创建一个字典,其中包含我们知道的有关用户的一切"""
  3. profile = {}
  4. profile['first_name'] = first
  5. profile['last_name'] = last
  6. for key, value in user_info.items():
  7. profile[key] = value
  8. return profile
  9. user_profile = build_profile('albert', 'einstein',
  10. location='princeton',
  11. field='physics')
  12. print(user_profile)

 

6. 将函数存储在模块中

  • 将函数存储在被称为模块 的独立文件中,再将模块导入 到主程序中。import 语句允许在当前运行的程序文件中使用模块中的代码。
  • 模块 是扩展名为.py的文件,包含要导入到程序中的代码。
  • 例子:
    ①我们将文件pizza.py中,除函数make_pizza() 之外的其他代码都删除。
    ②我们在pizza.py所在的目录中创建另一个名为making_pizzas.py的文件。
    ②在这个文件中用 import pizza 导入刚创建的模块,然后就可以在里面通过pizza.funname(),使用pizza.py中的函数了。

 

  • 你还可以导入模块中的特定函数,这种导入方法的语法如下:
    from module_name import function_0, function_1, function_2
    这种情况下,不用再用pizza.funname()调用,直接function_0()调用就好
  • 如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名 ——函数的另一个名称,类似于外号:from module_name import function_name as fn
  • 你还可以给模块指定别名。通过给模块指定简短的别名(如给模块pizza 指定别名p ),让你能够更轻松地调用模块中的函数:
    import module_name as mn

 

  • 使用星号(* )运算符可让Python导入模块中的所有函数:from module_name import *
  • 由于导入了每个函数,可通过名称来调用每个函数,而无需使用句点表示法。
  • 使用并非自己编写的大型模块时,最好不要采用这种导入方法:如果模块中有函数的名称与你的项目中使用的名称相同,可能导致意想不到的结果:Python可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有的函数。

 

第09章 类

1. 创建和使用类

  • 我们定义了一个名为Dog 的类。
  1. class Dog():
  2. """一次模拟小狗的简单尝试"""
  3. def __init__(self, name, age):
  4. """初始化属性name和age"""
  5. self.name = name
  6. self.age = age
  7. def sit(self):
  8. """模拟小狗被命令时蹲下"""
  9. print(self.name.title() + " is now sitting.")
  10. def roll_over(self):
  11. """模拟小狗被命令时打滚"""
  12. print(self.name.title() + " rolled over!")
  • 根据约定,在Python中,首字母大写的名称指的是类。
  • 类中的函数称为方法:你前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要的差别是调用方法的方式。
  • 方法__init__():这是一个特殊的方法,每当你根据Dog 类创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。
  • 我们将方法__init__() 定义成了包含三个形参:self 、name 和age 。

    在这个方法的定义中,形参self 必不可少,还必须位于其他形参的前面。为何必须在方法定义中包含形参self 呢?因为Python调用这个__init__() 方法来创建Dog 实例时,将自动传入实参self 。

    每个与类相关联的方法调用都自动传递实参self ,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
  • 我们创建Dog 实例时,Python将调用Dog 类的方法__init__() 。我们将通过实参向Dog() 传递名字和年龄;self 会自动传递,因此我们不需要传递它。每当我们根据Dog 类创建实例时,都只需给最后两个形参(name 和age )提供值。
  • Dog 类还定义了另外两个方法:sit() 和roll_over() 。由于这些方法不需要额外的信息,如名字或年龄,因此它们只有一个形参self。

 

  • 创建一个类的实例(对象):
  1. my_dog = Dog('willie', 6)
  2. print("My dog's name is " + my_dog.name.title() + ".")
  3. print("My dog is " + str(my_dog.age) + " years old.")

 

2. 使用类和实例

  • 类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。
  • 在有些情况下,如设置默认值时,在方法__init__() 内指定这种初始值是可行的;如果你对某个属性这样做了,就无需包含为它提供初始值的形参。
  1. class Car():
  2. def __init__(self, make, model, year):
  3. """初始化描述汽车的属性"""
  4. self.make = make
  5. self.model = model
  6. self.year = year
  7. self.odometer_reading = 0
  8. def get_descriptive_name(self):
  9. """返回整洁的描述性信息"""
  10. long_name = str(self.year) + ' ' + self.make + ' ' + self.model
  11. return long_name.title()
  12. def read_odometer(self):
  13. """打印一条指出汽车里程的消息"""
  14. print("This car has " + str(self.odometer_reading) + " miles on it.")
  15. #使用类
  16. my_new_car = Car('audi', 'a4', 2016)
  17. print(my_new_car.get_descriptive_name())
  18. my_new_car.read_odometer()

 

  • 可以以三种不同的方式修改属性的值:直接通过实例进行修改通过方法进行设置通过方法进行递增(增加特定的值)。

 

3.继承

  • 一个类继承 另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类 ,而新类称为子类
  • 子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

 

  • 创建子类时,父类必须包含在当前文件中,且位于子类前面。
  • super() 是一个特殊函数,帮助Python将父类和子类关联起来。通过super调用父类中的属性和方法。
  • 让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。
  • 对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
  • 我们还可以将另一个类的实例用作类的属性。

 

  • 例子:电动汽车是一种特殊的汽车,因此我们可以在前面创建的Car 类的基础上创建新类ElectricCar ,这样我们就只需为电动汽车特有的属性和行为编写代码。
  1. #父类:Car
  2. class Car():
  3. """一次模拟汽车的简单尝试"""
  4. def __init__(self, make, model, year):
  5. self.make = make
  6. self.model = model
  7. self.year = year
  8. self.odometer_reading = 0
  9. def get_descriptive_name(self):
  10. long_name = str(self.year) + ' ' + self.make + ' ' + self.model
  11. return long_name.title()
  12. def read_odometer(self):
  13. print("This car has " + str(self.odometer_reading) + " miles on it.")
  14. def update_odometer(self, mileage):
  15. if mileage >= self.odometer_reading:
  16. self.odometer_reading = mileage
  17. else:
  18. print("You can't roll back an odometer!")
  19. def increment_odometer(self, miles):
  20. self.odometer_reading += miles
  21. #另一个类:Battery
  22. class Battery():
  23. """一次模拟电动汽车电瓶的简单尝试"""
  24. def __init__(self, battery_size=70):
  25. """初始化电瓶的属性"""
  26. self.battery_size = battery_size
  27. def describe_battery(self):
  28. """打印一条描述电瓶容量的消息"""
  29. print("This car has a " + str(self.battery_size) + "-kWh battery.")
  30. def get_range(self):
  31. """打印一条消息,指出电瓶的续航里程"""
  32. if self.battery_size == 70:
  33. range = 240
  34. elif self.battery_size == 85:
  35. range = 270
  36. message = "This car can go approximately " + str(range)
  37. message += " miles on a full charge."
  38. print(message)
  39. #子类:ElectricCar
  40. class ElectricCar(Car):
  41. """电动汽车的独特之处"""
  42. def __init__(self, make, model, year):
  43. """
  44. 初始化父类的属性,再初始化电动汽车特有的属性
  45. """
  46. super().__init__(make, model, year)
  47. self.battery = Battery()
  48. #使用类
  49. my_tesla = ElectricCar('tesla', 'model s', 2016)
  50. print(my_tesla.get_descriptive_name())
  51. my_tesla.battery.describe_battery()
  52. my_tesla.battery.get_range()

 

4. 导入类

  • 和函数的操作类似。
  • 可根据需要在程序文件中导入任意数量的类。from car import Car, ElectricCar
  • 有时候,需要将类分散到多个模块中,以免模块太大,或在同一个模块中存储不相关的类。将类存储在多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类。在这种情况下,可在前一个模块中导入必要的类。

5. Python标准库

  • Python标准库 是一组模块,安装的Python都包含它。

 

  • 字典让你能够将信息关联起来,但它们不记录你添加键-值对的顺序。要创建字典并记录其中的键-值对的添加顺序,可使用模块collections 中的OrderedDict类。OrderedDict 实例的行为几乎与字典相同,区别只在于记录了键-值对的添加顺序。
  1. from collections import OrderedDict
  2. favorite_languages = OrderedDict()
  3. favorite_languages['jen'] = 'python'
  4. favorite_languages['sarah'] = 'c'
  5. favorite_languages['edward'] = 'ruby'
  6. favorite_languages['phil'] = 'python'
  7. for name, language in favorite_languages.items():
  8. print(name.title() + "'s favorite language is " +
  9. language.title() + ".")
  • 类名应采用驼峰命名法 ,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。
  • 对于每个类,都应紧跟在类定义后面包含一个文档字符串。每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。
  • 在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。
  • 需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import 语句,再添加一个空行,然后编写导入你自己编写的模块的import 语句。

 

第10章 文件和异常

1. 从文件中读取数据

  • 要以任何方式使用文件——哪怕仅仅是打印其内容,都得先打开 文件,这样才能访问它。函数open()接受一个参数:要打开的文件的名称。Python在当前执行的文件所在的目录中查找指定的文件。函数open() 返回一个表示文件的对象。
  • 关键字with 在不再需要访问文件后将其关闭(隐式地调用close()函数)。使用关键字with 时,open() 返回的文件对象只在with 代码块内可用。
  • 你也可以调用open() 和close() 来打开和关闭文件,但这样做时,如果程序存在bug,导致close() 语句未执行,文件将不会关闭。
  • 有了表示文件的对象后,我们使用方法read() 来读取这个文件的全部内容。
  • read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行。要删除多出来的空行,可在print 语句中使用rstrip() 。
  1. with open('pi_digits.txt') as file_object:
  2. contents = file_object.read()
  3. print(contents)
  • 有时候文件不在程序目录下,可写出完整路径去寻找:
  1. file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt'
  2. with open(file_path) as file_object:
  • 要以每次一行的方式检查文件,可对文件对象使用for 循环。
  1. filename = 'pi_digits.txt'
  2. with open(filename) as file_object:
  3. for line in file_object:
  4. print(line)

 

  • 可在with 代码块内将文件的各行存储在一个列表中,并在with 代码块外使用该列表:这样你可以立即处理文件的各个部分,也可推迟到程序后面再处理。
  • 方法readlines() 从文件中读取每一行,并将其存储在一个列表中。
  1. filename = 'pi_digits.txt'
  2. with open(filename) as file_object:
  3. lines = file_object.readlines()
  4. for line in lines:
  5. print(line.rstrip())

 

2. 写入文件

  • 要将文本写入文件,你在调用open() 时需要提供另一个实参'w',告诉Python你要写入打开的文件。
  • 调用open() 时提供了两个实参。第一个实参也是要打开的文件的名称;第二个实参('w' )告诉Python,我们要以写入模式 打开这个文件。
  • 打开文件时,可指定读取模式 ('r' )、写入模式 ('w' )、附加模式 ('a' )或让你能够读取和写入文件的模式('r+' )。如果你省略了模式实参,Python将以默认的只读模式打开文件。
  • 如果你要写入的文件不存在,函数open() 将自动创建它。然而,以写入('w' )模式打开文件时千万要小心,因为如果指定的文件已经存在,Python将在返回文件对象前清空该文件。
  • 如果你要给文件添加内容,而不是覆盖原有的内容,可以附加模式 打开文件。
  • Python只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数str() 将其转换为字符串格式。
  1. filename = 'programming.txt'
  2. with open(filename, 'w') as file_object:
  3. file_object.write("I love programming.")

 

3. 异常

  • Python使用被称为异常特殊对象来管理程序执行期间发生的错误。
  • 发生错误时,如果你编写了处理该异常的代码,程序将继续运行;如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。
  • 当你认为可能发生了错误时,可编写一个try-except 代码块来处理可能引发的异常。你让Python尝试运行一些代码,并告诉它如果这些代码引发了指定的异常,该怎么办。
  1. try:
  2. print(5/0)
  3. except ZeroDivisionError:
  4. print("You can't divide by zero!")

4. 存储数据

  • 模块json 让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。
  • 你还可以使用json 在Python程序之间分享数据。更重要的是,JSON数据格式并非Python专用的,这让你能够将以JSON格式存储的数据与使用其他编程语言的人分享。这是一种轻便格式,很有用,也易于学习。
    JSON(JavaScript Object Notation)格式最初是为JavaScript开发的,但随后成了一种常见格式,被包括Python在内的众多语言采用。

 

  • 函数json.dump() 接受两个实参:要存储的数据以及可用于存储数据的文件对象。
  1. import json
  2. numbers = [2, 3, 5, 7, 11, 13]
  3. filename = 'numbers.json'
  4. with open(filename, 'w') as f_obj:
  5. json.dump(numbers, f_obj)
  • 再使用函数json.load() 加载存储在numbers.json中的信息,并将其存储到变量numbers 中。
  1. import json
  2. filename = 'numbers.json'
  3. with open(filename) as f_obj:
  4. numbers = json.load(f_obj)
  5. print(numbers)

 

第11章 测试代码

1. 测试函数

  • 下面是一段手动测试函数的代码
  1. def get_formatted_name(first, last):
  2. """Generate a neatly formatted full name."""
  3. full_name = first + ' ' + last
  4. return full_name.title()
  5. print("Enter 'q' at any time to quit.")
  6. while True:
  7. first = input("\nPlease give me a first name: ")
  8. if first == 'q':
  9. break
  10. last = input("Please give me a last name: ")
  11. if last == 'q':
  12. break
  13. formatted_name = get_formatted_name(first, last)
  14. print("\tNeatly formatted name: " + formatted_name + '.')

 

  • Python中有模块unittest,专门用于测试。
  • 下面是一个只包含一个方法的测试用例,它检查函数get_formatted_name() 在给定名和姓时能否正确地工作。(通常测试文件和函数文件最好是两个文件,这里为了方便看放一起了)
  1. import unittest
  2. def get_formatted_name(first, last):
  3. """Generate a neatly formatted full name."""
  4. full_name = first + ' ' + last
  5. return full_name.title()
  6. class NamesTestCase(unittest.TestCase):
  7. """测试name_function.py"""
  8. def test_first_last_name(self):
  9. """能够正确地处理像Janis Joplin这样的姓名吗?"""
  10. formatted_name = get_formatted_name('janis', 'joplin')
  11. self.assertEqual(formatted_name, 'Janis Joplin')
  12. unittest.main()
  • 我们创建了一个名为NamesTestCase 的类,用于包含一系列针对get_formatted_name() 的单元测试。你可随便给这个类命名,但最好让它看起来与要测试的函数相关,并包含字样Test。这个类必须继承unittest.TestCase 类,这样Python才知道如何运行你编写的测试。
  • NamesTestCase 只包含一个方法,用于测试get_formatted_name() 的一个方面。我们将这个方法命名为test_first_last_name() ,因为我们要核实的是只有名和姓的姓名能否被正确地格式化。
  • 我们运行时,所有以test 打头的方法都将自动运行。在这个方法中,我们调用了要测试的函数,并存储了要测试的返回值。在这个示例中,我们使用实参'janis' 和'joplin' 调用get_formatted_name() ,并将结果存储到变量formatted_name 中。
  • 在这里,我们知道get_formatted_name() 应返回这样的姓名,即名和姓的首字母为大写,且它们之间有一个空格,因此我们期望formatted_name 的值为Janis Joplin 。为检查是否确实如此,我们调用unittest的方法assertEqual() ,并向它传递formatted_name 和'Janis Joplin' 。代码行self.assertEqual(formatted_name, 'Janis Joplin') 的意思是说:“将formatted_name 的值同字符串'Janis Joplin' 进行比较,如果它们相等,就万事大吉,如果它们不相等,跟我说一声!”

2. 测试类

  • Python在unittest.TestCase 类中提供了很多断言方法。前面说过,断言方法检查你认为应该满足的条件是否确实满足。如果该条件确实满足,你对程序行为的假设就得到了确认,你就可以确信其中没有错误。如果你认为应该满足的条件实际上并不满足,Python将引发异常。

  • 我们首先导入了模块unittest 以及要测试的类AnonymousSurvey 。我们将测试用例命名为TestAnonymousSurvey ,它也继承了unittest.TestCase。第一个测试方法验证调查问题的单个答案被存储后,会包含在调查结果列表中。对于这个方法,一个不错的描述性名称是test_store_single_response() 。如果这个测试未通过,我们就能通过输出中的方法名得知,在存储单个调查答案方面存在问题。
    要测试类的行为,需要创建其实例。我们使用问题"What language did you first learn to speak?" 创建了一个名为my_survey 的实例,然后使用方法store_response() 存储了单个答案English 。接下来,我们检查English 是否包含在列表my_survey.responses 中,以核实这个答案是否被妥善地存储了
  1. import unittest
  2. from survey import AnonymousSurvey
  3. class TestAnonmyousSurvey(unittest.TestCase):
  4. """针对AnonymousSurvey类的测试"""
  5. def test_store_single_response(self):
  6. """测试单个答案会被妥善地存储"""
  7. question = "What language did you first learn to speak?"
  8. my_survey = AnonymousSurvey(question)
  9. my_survey.store_response('English')
  10. self.assertIn('English', my_survey.responses)
  11. unittest.main()
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号