【学习注意事项】Python编程:从入门到实践(持续整理中~)

记录一下我的学习~
记录了我所认为值得注意的一些细节~

第二章:变量和简单数据类型
2.2 变量

  1. 在程序中可随时修改变量的值,而Python将始终记录变量的最新值。
    2.2.1 变量的命名和使用

  2. 变量名只能包含字母、数字和下划线。变量名可以字母或下划线打头,但不能以数字打头,例如,可将变量命名为message_1,但不能将其命名为1_message。

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

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

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

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

  7. 注意 就目前而言,应使用小写的Python变量名。
    2.2.2 使用变量时避免命名错误

  8. eg:NameError: name ‘mesage’ is not defined(要么是使用变量前忘记了给它赋值,要么是输入变量名时拼写不正确。)
    2.3 字符串

  9. 字符串就是一系列字符。在Python中,用引号括起的都是字符串,其中的引号可以是单引号,也可以是双引号。
    2.3.1 使用方法修改字符串的大小写

  10. 对于字符串,可执行的最简单的操作之一是修改其中的单词的大小写。

  11. 在 print() 语句中,方法title() 出现在这个变量的后面。方法是Python可对数据执行的操作。title() 以首字母大写的方式显示每个单词,即将每个单词的首字母都改为大写。

  12. upper(),全部大写。

  13. lower(),全部小写。
    2.3.3 使用制表符或换行符来添加空白

  14. 空白泛指任何非打印字符,如空格、制表符和换行符。

  15. 要在字符串中添加制表符,可使用字符组合 \t。

  16. 还可在同一个字符串中同时包含制表符和换行符。字符串 “\n\t” 让Python换到下一行,并在下一行开头添加一个制表符。
    2.3.4 删除空白

  17. rstrip(),删除尾端空白。

  18. lstrip(),删除开头空白。

  19. strip(),删除两端空白。

  20. 这些剥除函数最常用于在存储用户输入前对其进行清理。
    2.3.5 使用字符串时避免语法错误

  21. 第一个单引号和撇号之间的内容视为一个字符串,进而将余下的文本视为Python代码,从而引发错误。
    2.3.6 Python 2 中的 print 语句

  22. 在Python 2中,无需将要打印的内容放在括号内。从技术上说,Python 3中的 print 是一个函数,因此括号必不可少。有些Python 2 print 语句也包含括号,但其行为与Python 3中稍有不同。简单地说,在Python 2代码中,有些 print 语句包含括号,有些不包含。
    2.4.3 使用函数 str() 避免类型错误

  23. 函数 str() ,它让Python将非字符串值表示为字符串。
    2.6 Python 之禅

  24. Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren’t special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you’re Dutch.
    Now is better than never.
    Although never is often better than right now.
    If the implementation is hard to explain, it’s a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea – let’s do more of those!
    第三章:列表简介
    3.1 列表是什么

  25. 列表由一系列按特定顺序排列的元素组成。

  26. 在Python中,用方括号( [] )来表示列表,并用逗号来分隔其中的元素。
    3.1.2 索引从 0 而不是 1 开始

  27. 在Python中,第一个列表元素的索引为0,而不是1。

  28. Python为访问最后一个列表元素提供了一种特殊语法。通过将索引指定为 -1 ,可让Python返回最后一个列表元素。索引 -2 返回倒数第二个列表元素,索引 -3 返回倒数第三个列表元素,以此类推。
    3.2.2 在列表中添加元素

  29. 方法 append() 将元素 ‘ducati’ 添加到了列表末尾。

  30. 使用方法 insert() 可在列表的任何位置添加新元素。为此,你需要指定新元素的索引和值。
    3.2.3 从列表中删除元素

  31. 如果知道要删除的元素在列表中的位置,可使用 del 语句。

  32. 方法 pop() 可删除列表末尾的元素,并让你能够接着使用它。你可以使用 pop() 来删除列表中任何位置的元素,只需在括号中指定要删除的元素的索引即可。

  33. 如果你不确定该使用 del 语句还是 pop() 方法,下面是一个简单的判断标准:如果你要从列表中删除一个元素,且不再以任何方式使用它,就使用 del 语句;如果你要在删除元素后还能继续使用它,就使用方法 pop() 。

  34. 有时候,你不知道要从列表中删除的值所处的位置。如果你只知道要删除的元素的值,可使用方法 remove() 。

  35. 使用 remove() 从列表中删除元素时,也可接着使用它的值。

  36. 注意 方法 remove() 只删除第一个指定的值。如果要删除的值可能在列表中出现多次,就需要使用循环来判断是否删除了所有这样的值。
    3.3.1 使用方法 sort() 对列表进行永久性排序

  37. Python方法 sort() 让你能够较为轻松地对列表进行排序。按字母顺序排列。

  38. 要保留列表元素原来的排列顺序,同时以特定的顺序呈现它们,可使用函数 sorted() 。函数sorted() 让你能够按特定顺序显示列表元素,同时不影响它们在列表中的原始排列顺序。

  39. 注意,调用函数 sorted() 后,列表元素的排列顺序并没有变。如果你要按与字母顺序相反的顺序显示列表,也可向函数 sorted() 传递参数 reverse=True 。
    3.3.3 倒着打印列表

  40. 要反转列表元素的排列顺序,可使用方法 reverse() 。

  41. 注意, reverse() 不是指按与字母顺序相反的顺序排列列表元素,而只是反转列表元素的排列顺序。

  42. 方法 reverse() 永久性地修改列表元素的排列顺序,但可随时恢复到原来的排列顺序,为此只需对列表再次调用 reverse() 即可。
    3.3.4 确定列表的长度

  43. 使用函数 len() 可快速获悉列表的长度。
    第四章:操作类表
    4.1 遍历整个列表

  44. 可使用Python中的 for 循环。
    4.2.1 忘记缩进

  45. 对于位于 for 语句后面且属于循环组成部分的代码行,一定要缩进。如果你忘记缩进,Python会提醒你。

  46. 通常,将紧跟在 for 语句后面的代码行缩进,可消除这种缩进错误。
    4.2.2 忘记缩进额外的代码行

  47. 如果你预期某项操作将针对每个列表元素都执行一次,但它却只执行了一次,请确定是否需要将一行或多行代码缩进。
    4.2.3 不必要的缩进

  48. 为避免意外缩进错误,请只缩进需要缩进的代码。在前面编写的程序中,只有要在 for 循环中对每个元素执行的代码需要缩进。
    4.3 创建数值列表
    4.3.1 使用函数 range()

  49. .Python函数 range() 让你能够轻松地生成一系列的数字。

  50. 使用 range() 时,如果输出不符合预期,请尝试将指定的值加1或减1。
    4.3.2 使用 range() 创建数字列表

  51. 要创建数字列表,可使用函数 list() 将 range() 的结果直接转换为列表。如果将 range() 作为list() 的参数,输出将为一个数字列表。

  52. 使用函数 range() 时,还可指定步长。

  53. 在Python中,两个星号( ** )表示乘方运算。
    4.3.3 对数字列表执行简单的统计计算

  54. 有几个专门用于处理数字列表的Python函数。(min(),max(),sum())

  55. 注意 出于版面考虑,本节使用的数字列表都很短,但这里介绍的知识也适用于包含数百万个数字的列表。
    4.4 使用列表的一部分

  56. 你一直在学习如何处理列表的所有元素。你还可以处理列表的部分元素——Python称之为切片。
    4.4.1 切片

  57. 要创建切片,可指定要使用的第一个元素和最后一个元素的索引。

  58. 如果你没有指定第一个索引,Python将自动从列表开头开始.

  59. 要让切片终止于列表末尾,也可使用类似的语法。
    4.4.2 遍历切片

  60. 如果要遍历列表的部分元素,可在 for 循环中使用切片。
    4.4.3 复制列表

  61. 要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引( [:] )。这让Python创建一个始于第一个元素,终止于最后一个元素的切片,即复制整个列表。
    4.5 元组

  62. Python将不能修改的值称为不可变的,而不可变的列表被称为元组。
    4.5.1 定义元组

  63. 元组看起来犹如列表,但使用圆括号而不是方括号来标识。定义元组后,就可以使用索引来访问其元素,就像访问列表元素一样。

  64. 由于试图修改元组的操作是被禁止的,因此Python指出不能给元组的元素赋值。
    4.5.3 修改元组变量

  65. 虽然不能修改元组的元素,但可以给存储元组的变量赋值。因此,如果要修改前述矩形的尺寸,可重新定义整个元组。
    4.6 设置代码格式

  66. 随着你编写的程序越来越长,有必要了解一些代码格式设置约定。
    4.6.2 缩进

  67. PEP 8建议每级缩进都使用四个空格。
    4.6.3 行长

  68. 很多Python程序员都建议每行不超过80字符。PEP 8还建议注释的行长都不超过72字符。
    4.6.4 空行

  69. 要将程序的不同部分分开,可使用空行。

  70. PEP 8格式设置指南:请访问 https://python/dev/peps/pep-0008/。
    第五章:if 语句
    5.2 条件测试

  71. 每条 if 语句的核心都是一个值为 True 或 False 的表达式,这种表达式被称为条件测试。Python根据条件测试的值为 True 还是 False 来决定是否执行 if 语句中的代码。如果条件测试的值为 True ,Python就执行紧跟在 if 语句后面的代码;如果为 False , Python 就忽略这些代码。
    5.2.1 检查是否相等

  72. 大多数条件测试都将一个变量的当前值同特定值进行比较。最简单的条件测试检查变量的值是否与特定值相等。

  73. 一个等号是陈述,两个等号是发问。
    5.2.2 检查是否相等时不考虑大小写

  74. 在Python中检查是否相等时区分大小写,两个大小写不同的值会被视为不相等。

  75. 函数 lower()不会修改存储在变量 car 中的值,因此进行这样的比较时不会影响原来的变量。
    5.2.3 检查是否不相等

  76. 要判断两个值是否不等,可结合使用惊叹号和等号( != ),其中的惊叹号表示不,在很多编程语言中都如此。
    5.2.4 比较数字

  77. 条件语句中可包含各种数学比较,如小于、小于等于、大于、大于等于。
    5.2.5 检查多个条件
    1. 使用 and 检查多个条件

  78. 要检查是否两个条件都为 True ,可使用关键字 and 将两个条件测试合而为一。

  79. 为改善可读性,可将每个测试都分别放在一对括号内,但并非必须这样做。
    2. 使用 or 检查多个条件

  80. 关键字 or 也能够让你检查多个条件,但只要至少有一个条件满足,就能通过整个测试。仅当两个测试都没有通过时,使用 or 的表达式才为 False 。
    5.2.6 检查特定值是否包含在列表中

  81. 要判断特定的值是否已包含在列表中,可使用关键字 in 。
    5.2.7 检查特定值是否不包含在列表中

  82. 还有些时候,确定特定的值未包含在列表中很重要;在这种情况下,可使用关键字 not in 。
    5.2.8 布尔表达式

  83. 布尔表达式,它不过是条件测试的别名。与条件表达式一样,布尔表达式的结果要么为 True ,要么为 False 。
    5.3 if 语句

  84. 在 if 语句中,缩进的作用与 for 循环中相同。如果测试通过了,将执行 if 语句后面所有缩进的代码行,否则将忽略它们。
    5.3.2 if-else 语句

  85. if-else 语句块类似于简单的 if 语句,但其中的 else 语句让你能够指定条件测试未通过时要执行的操作。
    5.3.3 if-elif-else 结构

  86. Python只执行if-elif-else 结构中的一个代码块,它依次检查每个条件测试,直到遇到通过了的条件测试。测试通过后,Python将执行紧跟在它后面的代码,并跳过余下的测试。
    5.3.5 省略 else 代码块

  87. Python并不要求 if-elif 结构后面必须有 else 代码块。在有些情况下, else 代码块很有用;而在其他一些情况下,使用一条 elif 语句来处理特定的情形更清晰。

  88. 总之,如果你只想执行一个代码块,就使用 if-elif-else 结构;如果要运行多个代码块,就使用一系列独立的 if 语句。
    5.4.2 确定列表不是空的

  89. 在 if 语句中将列表名用在条件表达式中时,Python将在列表至少包含一个元素时返回 True ,并在列表为空时返回 False 。

  90. **习题:**序数:序数表示位置,如 1st和 2nd。大多数序数都以 th结尾,只有 1、2和 3例外。
     在一个列表中存储数字 1~9。
     遍历这个列表。
     在循环中使用一个 if-elif-else 结构,以打印每个数字对应的序数。输出内容
    应为 1st 、 2nd 、 3rd 、 4th 、 5th 、 6th 、 7th 、 8th 和 9th , 但每个序数都独占一行。
    本题答案
    5.5 设置 if 语句的格式

  91. 在诸如 == 、 >= 和 <= 等比较运算符两边各添加一个空格,例如, if age < 4: 要比 if age<4: 好。
    第六章:字典

  92. 使用字典一段时间后,你就会明白为何它们能够高效地模拟现实世界中的情形。
    6.2 使用字典

  93. 在Python中,字典是一系列键 — 值对。每个键都与一个值相关联,你可以使用键来访问与之相关联的值。与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可将任何Python对象用作字典中的值。

  94. 在Python中,字典用放在花括号 {} 中的一系列键 — 值对表示。

  95. 键 — 值对是两个相关联的值。指定键时,Python将返回与之相关联的值。键和值之间用冒号分隔,而键 — 值对之间用逗号分隔。
    6.2.2 添加键 — 值对

  96. 注意,键 — 值对的排列顺序与添加顺序不同。Python不关心键 — 值对的添加顺序,而只关心键和值之间的关联关系。
    6.2.5 删除键 — — 值对

  97. 对于字典中不再需要的信息,可使用 del 语句将相应的键 — 值对彻底删除。使用 del 语句时,必须指定字典名和要删除的键。

  98. 注意 删除的键 — 值对永远消失了。

  99. **习题:**喜欢的数字:使用一个字典来存储一些人喜欢的数字。请想出 5个人的名字,并将这些名字用作字典中的键;想出每个人喜欢的一个数字,并将这些数字作为值存储在字典中。打印每个人的名字和喜欢的数字。
    本题答案
    6.3.1 遍历所有的键 — — 值对

  100. 要编写用于遍历字典的 for 循环,可声明两个变量,用于存储键 — 值对中的键和值。对于这两个变量,可使用任何名称。(for k, v in user_0.items())

  101. 注意,即便遍历字典时,键 — 值对的返回顺序也与存储顺序不同。Python不关心键 — 值对的存储顺序,而只跟踪键和值之间的关联关系。
    6.3.2 遍历字典中的所有键

  102. 在不需要使用字典中的值时,方法 keys() 很有用。

  103. 方法 keys() 并非只能用于遍历;实际上,它返回一个列表,其中包含字典中的所有键。
    6.3.3 按顺序遍历字典中的所有键

  104. 字典总是明确地记录键和值之间的关联关系,但获取字典的元素时,获取顺序是不可预测的。

  105. 要以特定的顺序返回元素,一种办法是在 for 循环中对返回的键进行排序。(for name in sorted(favorite_languages.keys()))
    6.3.4 遍历字典中的所有值

  106. 如果你感兴趣的主要是字典包含的值,可使用方法 values() ,它返回一个值列表,而不包含任何键。

  107. 为剔除重复项,可使用集合(set)。集合类似于列表,但每个元素都必须是独一无二的。(for language in set(favorite_languages.values()))

  108. 通过对包含重复元素的列表调用 set() ,可让Python找出列表中独一无二的元素,并使用这些元素来创建一个集合。

  109. **习题:**河流:创建一个字典,在其中存储三条大河流及其流经的国家。其中一个键 —值对可能是 ‘nile’: ‘egypt’ 。
     使用循环为每条河流打印一条消息,如“The Nile runs through Egypt.”。
    使用循环将该字典中每条河流的名字都打印出来。
    使用循环将该字典包含的每个国家的名字都打印出来。
    本题答案
    6.4 嵌套

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

  111. 有时候,需要将列表存储在字典中,而不是将字典存储在列表中。

  112. 每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。

  113. 注意 列表和字典的嵌套层级不应太多。如果嵌套层级比前面的示例多得多,很可能有更简单的解决问题的方案。
    6.4.3 在字典中存储字典

  114. 可在字典中嵌套字典,但这样做时,代码可能很快复杂起来。

  115. 请注意,表示每位用户的字典的结构都相同,虽然Python并没有这样的要求,但这使得嵌套的字典处理起来更容易。倘若表示每位用户的字典都包含不同的键, for 循环内部的代码将更复杂。
    第七章:用户输入和 while 循环
    7.1 函数 input() 的工作原理

  116. 函数 input() 让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python将其存储在一个变量中,以方便你使用。
    7.1.1 编写清晰的程序

  117. 每当你使用函数 input() 时,都应指定清晰而易于明白的提示,准确地指出你希望用户提供什么样的信息——指出用户该输入任何信息的提示都行。

  118. 有时候,提示可能超过一行,例如,你可能需要指出获取特定输入的原因。在这种情况下,可将提示存储在一个变量中,再将该变量传递给函数 input() 。这样,即便提示超过一行, input()语句也非常清晰。

  119. 运算符 += 在存储在 prompt 中的字符串末尾附加一个字符串。
    7.1.2 使用 int() 来获取数值输入

  120. 我们怎么知道Python将输入解读成了字符串呢?因为这个数字用引号括起
    了。如果我们只想打印输入,这一点问题都没有;但如果你试图将输入作为数字使用,就会引发错误。

  121. 可使用函数 int() ,它让Python将输入视为数值。函数 int() 将数字的字符
    串表示转换为数值表示。

  122. 将数值输入用于计算和比较前,务必将其转换为数值表示。
    7.1.3 求模运算符

  123. 处理数值信息时,求模运算符( % )是一个很有用的工具,它将两个数相除并返回余数。

  124. 求模运算符不会指出一个数是另一个数的多少倍,而只指出余数是多少。

  125. 如果一个数可被另一个数整除,余数就为0,因此求模运算符将返回0。你可利用这一点来判断一个数是奇数还是偶数。
    7.1.4 在 Python 2.7 中获取输入

  126. 如果你使用的是Python 2.7,应使用函数 raw_input() 来提示用户输入。这个函数与Python 3中的 input() 一样,也将输入解读为字符串。

  127. **习题:**餐馆订位:编写一个程序,询问用户有多少人用餐。如果超过 8人,就打印一 条消息,指出没有空桌;否则指出有空桌。
    本题答案
    7.2 while 循环简介

  128. for 循环用于针对集合中的每个元素都一个代码块,而 while 循环不断地运行,直到指定的条件不满足为止。
    7.2.2 让用户选择何时退出

  129. 我们将变量 message 的初始值设置为空字符串 “” ,让Python首次执行 while 代码行时有可供检查的东西。

  130. 如果没有可供比较的东西,Python将无法继续运行程序。为解决这个问题,
    我们必须给变量 message 指定一个初始值。虽然这个初始值只是一个空字符串,但符合要求,让Python能够执行 while 循环所需的比较。只要 message 的值不是 ‘quit’ ,这个循环就会不断运行。
    7.2.3 使用标志

  131. 在要求很多条件都满足才继续运行的程序中,可定义一个变量,用于判断整个程序是否处于活动状态。

  132. 你可让程序在标志为 True 时继续运行,并在任何事件导致标志的值为 False 时让程序停止运行。

  133. 在 while 语句中就只需检查一个条件——标志的当前值是否为 True ,并将所有测试(是否发生了应将标志设置为 False 的事件)都放在其他地方,从而让程序变得更为整洁。
    7.2.4 使用 break 退出循环

  134. 要立即退出 while 循环,不再运行循环中余下的代码,也不管条件测试的结果如何,可使用break 语句。 break 语句用于控制程序流程,可使用它来控制哪些代码行将执行,哪些代码行不执行,从而让程序按你的要求执行你要执行的代码。

  135. 我们可以在用户输入’quit’ 后使用 break 语句立即退出 while 循环。

  136. 以 while True 打头的循环将不断运行,直到遇到 break 语句。

  137. 注意 在任何Python循环中都可使用 break 语句。例如,可使用 break 语句来退出遍历列表或字典的 for 循环。
    7.2.5 在循环中使用 continue

  138. 要返回到循环开头,并根据条件测试结果决定是否继续执行循环,可使用continue 语句,它不像 break 语句那样不再执行余下的代码并退出整个循环。
    7.2.6 避免无限循环

  139. 每个 while 循环都必须有停止运行的途径,这样才不会没完没了地执行下去。

  140. 每个程序员都会偶尔因不小心而编写出无限循环,在循环的退出条件比较微妙时尤其如此。如果程序陷入无限循环,可按Ctrl + C,也可关闭显示程序输出的终端窗口。

  141. 注意 有些编辑器(如Sublime Text)内嵌了输出窗口,这可能导致难以结束无限循环,因此不得不关闭编辑器来结束无限循环。

  142. **习题:**电影票:有家电影院根据观众的年龄收取不同的票价:不到3岁的观众免费; 3~12岁的观众为10美元;超过12岁的观众为15美元。请编写一个循环,在其中询问用户的年龄,指出其票价。
    本题答案
    7.3 使用 while 循环来处理列表和字典

  143. 要记录大量的用户和信息,需要在 while 循环中使用列表和字典。

  144. for 循环是一种遍历列表的有效方式,但在 for 循环中不应修改列表,否则将导致Python难以跟踪其中的元素。要在遍历列表的同时对其进行修改,可使用 while 循环。通过将 while 循环同列表和字典结合起来使用,可收集、存储并组织大量输入,供以后查看和显示。
    7.3.1 在列表之间移动元素

  145. 假设有一个列表,其中包含新注册但还未验证的网站用户;验证这些用户后,如何将他们移到另一个已验证用户列表中呢?一种办法是使用一个 while 循环,在验证用户的同时将其从未验证用户列表中提取出来,再将其加入到另一个已验证用户列表中。
    7.3.2 删除包含特定值的所有列表元素

  146. 在第3章中,我们使用函数 remove() 来删除列表中的特定值。

  147. 假设你有一个宠物列表,其中包含多个值为 ‘cat’ 的元素。要删除所有这些元素,可不断运行一个 while 循环,直到列表中不再包含值 ‘cat’。
    eg:while ‘cat’ in pets:
    pets.remove(‘cat’)
    7.3.3 使用用户输入来填充字典

  148. 可使用 while 循环提示用户输入任意数量的信息。

  149. **习题1:**熟食店:创建一个名为 sandwich_orders 的列表,在其中包含各种三明治的名字;再创建一个名为 finished_sandwiches 的空列表。遍历列表 sandwich_orders ,对于其中的每种三明治,都打印一条消息,如 I made your tuna sandwich ,并将其移到列表finished_sandwiches 。所有三明治都制作好后,打印一条消息,将这些三明治列出来。
    本题答案

  150. **习题2:**梦想的度假胜地:编写一个程序,调查用户梦想的度假胜地。使用类似于“If you could visit one place in the world, where would you go?”的提示,并编写一个打印调查结果的代码块。

  151. 本题答案
    第八章:函数
    8.1 定义函数

  152. 使用关键字 def 来告诉Python你要定义一个函数。这是函数定义,向Python指出了函数名,还可能在括号内指出函数为完成其任务需要什么样的信息。
    8.1.1 向函数传递信息

  153. 通过在这里添加 username ,就可让函数接受你给 username 指定的任何值。现在,这个函数要求你调用它时给 username 指定一个值。调用 greet_user() 时,可将一个名字传递给它。
    eg:def greet_user(username):
    “”" 显示简单的问候语 “”"
    print("Hello, " + username.title() + “!”)
    greet_user(‘jesse’)
    8.1.2 实参和形参

  154. 变量 username 是一个形参——函数完成其工作所需的一项信息。在代码greet_user(‘jesse’) 中,值 ‘jesse’ 是一个实参。实参是调用函数时传递给函数的信息。

  155. 注意 大家有时候会形参、实参不分,因此如果你看到有人将函数定义中的变量称为实参或将函数调用中的变量称为形参,不要大惊小怪。

  156. **习题:**喜欢的图书:编写一个名为 favorite_book() 的函数,其中包含一个名为 title的形参。这个函数打印一条消息,如 One of my favorite books is Alice in Wonderland 。调用这个函数,并将一本图书的名称作为实参传递给它。
    本题答案
    8.2 传递实参

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

  158. 你调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。

  159. 你可以根据需要调用函数任意次。

  160. 使用位置实参来调用函数时,如果实参的顺序不正确,结果可能出乎意料。
    8.2.2 关键字实参

  161. 关键字实参是传递给函数的名称 — 值对。

  162. 关键字实参让你无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。

  163. 注意 使用关键字实参时,务必准确地指定函数定义中的形参名。
    8.2.3 默认值

  164. 编写函数时,可给每个形参指定默认值。

  165. 在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。因此,给形参指定默认值后,可在函数调用中省略相应的实参。使用默认值可简化函数调用,还可清楚地指出函数的典型用法。

  166. 注意 使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参。这让Python依然能够正确地解读位置实参。
    8.2.4 等效的函数调用

  167. 鉴于可混合使用位置实参、关键字实参和默认值,通常有多种等效的函数调用方式。

  168. 注意 使用哪种调用方式无关紧要,只要函数调用能生成你希望的输出就行。使用对你来说最容易理解的调用方式即可。
    8.2.5 避免实参错误

  169. 等你开始使用函数后,如果遇到实参不匹配错误,不要大惊小怪。你提供的实参多于或少于函数完成其工作所需的信息时,将出现实参不匹配错误。
    8.3 返回值

  170. 函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值。函数返回的值被称为返回值。
    8.3.2 让实参变成可选的

  171. 然而,并非所有的人都有中间名,但如果你调用这个函数时只提供了名和姓,它将不能正确地运行。为让中间名变成可选的,可给实参 middle_name 指定一个默认值——空字符串,并在用户没有提供中间名时不使用这个实参。
    8.3.3 返回字典

  172. 函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。

  173. **习题:**城市名:编写一个名为 city_country() 的函数,它接受城市的名称及其所属的
    国家。这个函数应返回一个格式类似于下面这样的字符串:
    “Santiago, Chile”
    至少使用三个城市国家对调用这个函数,并打印它返回的值。
    本题答案
    8.4.2 禁止函数修改列表

  174. 要将列表的副本传递给函数,可以像下面这样做:
    function_name ( list_name [:])
    切片表示法 [:] 创建列表的副本。

  175. 如果不想清空未打印的设计列表,可像下面这样调用 print_models() :
    print_models(unprinted_designs[:], completed_models)

  176. 虽然向函数传递列表的副本可保留原始列表的内容,但除非有充分的理由需要传递副本,否则还是应该将原始列表传递给函数,因为让函数使用现成列表可避免花时间和内存创建副本,从而提高效率,在处理大型列表时尤其如此。

  177. **习题:**魔术师:创建一个包含魔术师名字的列表,并将其传递给一个名为 show_magicians() 的函数,这个函数打印列表中每个魔术师的名字。
    本题答案
    8.5 传递任意数量的实参

  178. 有时候,你预先不知道函数需要接受多少个实参,好在Python允许函数从调用语句中收集任意数量的实参。

  179. 下面的函数只有一个形参 *toppings ,但不管调用语句提供了多少实参,这个形参都将它们统统收入囊中。

  180. 形参名 *toppings 中的星号让Python创建一个名为 toppings 的空元组,并将收到的所有值都封装到这个元组中。函数体内的 print 语句通过生成输出来证明Python能够处理使用一个值调用函数的情形,也能处理使用三个值来调用函数的情形。
    8.5.1 结合使用位置实参和任意数量实参

  181. 如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
    8.5.2 使用任意数量的关键字实参

  182. 有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键 — 值对——调用语句提供了多少就接受多少。

  183. **习题:**三明治:编写一个函数,它接受顾客要在三明治中添加的一系列食材。这个函数只有一个形参(它收集函数调用中提供的所有食材),并打印一条消息,对顾客点的三明治进行概述。调用这个函数三次,每次都提供不同数量的实参。
    本题答案
    8.6 将函数存储在模块中

  184. 函数的优点之一是,使用它们可将代码块与主程序分离。通过给函数指定描述性名称,可让主程序容易理解得多。

  185. 将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。 import 语句允许在当前运行的程序文件中使用模块中的代码。

  186. 将函数存储在独立文件中后,可与其他程序员共享这些文件而不是整个程序。
    8.6.1 导入整个模块

  187. 要让函数是可导入的,得先创建模块。

  188. Python读取这个文件时,代码行 import pizza 让Python打开文件pizza.py,并将其中的所有函数都复制到这个程序中。你看不到复制的代码,因为这个程序运行时,Python在幕后复制这些代码。你只需知道,在making_pizzas.py中,可以使用pizza.py中定义的所有函数。
    8.6.2 导入特定的函数

  189. 你还可以导入模块中的特定函数,这种导入方法的语法如下:
    from module_name import function_name

  190. 通过用逗号分隔函数名,可根据需要从模块中导入任意数量的函数:
    from module_name import function_0 , function_1 , function_2
    8.6.3 使用 as 给函数指定别名

  191. 如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名——函数的另一个名称,类似于外号。
    8.6.4 使用 as 给模块指定别名

  192. 你还可以给模块指定别名。

  193. 这样不仅能使代码更简洁,还可以让你不再关注模块名,而专注于描述性的函数名。这些函数名明确地指出了函数的功能,对理解代码而言,它们比模块名更重要。
    8.6.5 导入模块中的所有函数

  194. 使用星号( * )运算符可让Python导入模块中的所有函数。

  195. 由于导入了每个函数,可通过名称来调用每个函数,而无需使用句点表示法。

  196. 使用并非自己编写的大型模块时,最好不要采用这种导入方法:如果模块中有函数的名称与你的项目中使用的名称相同,可能导致意想不到的结果。

  197. Python可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有的函数。

  198. 最佳的做法是,要么只导入你需要使用的函数,要么导入整个模块并使用句点表示法。
    8.7 函数编写指南

  199. 编写函数时,需要牢记几个细节。应给函数指定描述性名称,且只在其中使用小写字母和下划线。

  200. 描述性名称可帮助你和别人明白代码想要做什么。给模块命名时也应遵循上述约定。

  201. 每个函数都应包含简要地阐述其功能的注释,该注释应紧跟在函数定义后面,并采用文档字符串格式。

  202. 文档良好的函数让其他程序员只需阅读文档字符串中的描述就能够使用它。

  203. 只要知道函数的名称、需要的实参以及返回值的类型,就能在自己的程序中使用它。

  204. 给形参指定默认值时,等号两边不要有空格。

  205. 对于函数调用中的关键字实参,也应遵循这种约定。

  206. 如果形参很多,导致函数定义的长度超过了79字符,可在函数定义中输入左括号后按回车键,并在下一行按两次Tab键,从而将形参列表和只缩进一层的函数体区分开来。

  207. 如果程序或模块包含多个函数,可使用两个空行将相邻的函数分开,这样将更容易知道前一个函数在什么地方结束,下一个函数从什么地方开始。

  208. 所有的 import 语句都应放在文件开头,唯一例外的情形是,在文件开头使用了注释来描述整个程序。
    第九章:类
    9.1 创建和使用类

  209. 使用类几乎可以模拟任何东西。

  210. 在Python中,首字母大写的名称指的是类。这个类定义中的括号是空的,因为我们要从空白创建这个类。
    方法 init()

  211. 类中的函数称为方法;你前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要的差别是调用方法的方式。

  212. 方法 init() 是一个特殊的方法,每当你根据 Dog 类创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。

  213. 形参 self 必不可少,还必须位于其他形参的前面。

  214. 通过实例访问的变量称为属性。
    9.1.2 根据类创建实例

  215. 我们通常可以认为首字母大写的名称(如Dog )指的是类,而小写的名称(如 my_dog )指的是根据类创建的实例。

  216. 要访问实例的属性,可使用句点表示法。

  217. 可按需求根据类创建任意数量的实例。

  218. 就算我们给第二条小狗指定同样的名字和年龄,Python依然会根据 Dog 类创建另一个实例。你可按需求根据一个类创建任意数量的实例,条件是将每个实例都存储在不同的变量中,或占用列表或字典的不同位置。

  219. 习题:餐馆:创建一个名为 Restaurant 的类,其方法 init() 设置两个属性:restaurant_name 和 cuisine_type 。创建一个名为 describe_restaurant() 的方法和一个名为 open_restaurant() 的方法,其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。根据这个类创建一个名为 restaurant 的实例,分别打印其两个属性,再调用前述两个方法。
    本题答案
    9.2 使用类和实例

  220. 你可以使用类来模拟现实世界中的很多情景。
    9.2.2 给属性指定默认值

  221. 类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。
    9.2.3 修改属性的值

  222. 可以以三种不同的方式修改属性的值:直接通过实例进行修改;通过方法进行设置;通过方法进行递增(增加特定的值)。下面依次介绍这些方法。

  223. 要修改属性的值,最简单的方式是通过实例直接访问它。

  224. 有时候需要像这样直接访问属性,但其他时候需要编写对属性进行更新的方法。

  225. 如果有替你更新属性的方法,将大有裨益。这样,你就无需直接访问属性,而可将值传递给一个方法,由它在内部进行更新。

  226. 注意 你可以使用类似于上面的方法来控制用户修改属性值(如里程表读数)的方式,但能够访问程序的人都可以通过直接访问属性来将里程表修改为任何值。要确保安全,除了进行类似于前面的基本检查外,还需特别注意细节。

  227. 习题:就餐人数:在为完成练习 9-1 而编写的程序中,添加一个名为 number_served的属性,并将其默认值设置为 0。根据这个类创建一个名为 restaurant 的实例;打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。 添加一个名为 set_number_served() 的方法,它让你能够设置就餐人数。调用这个 方法并向它传递一个值,然后再次打印这个值。 添加一个名为 increment_number_served() 的方法,它让你能够将就餐人数递增。 调用这个方法并向它传递一个这样的值:你认为这家餐馆每天可能接待的就餐人数。
    本题答案
    9.3 继承

  228. 编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
    9.3.1 子类的方法 init()

  229. 创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法 init() 需要父类施以援手。

  230. 创建子类时,父类必须包含在当前文件中,且位于子类前面。

  231. 定义子类时,必须在括号内指定父类的名称。

  232. 父类也称为超类(superclass),名称super因此而得名。
    9.3.3 给子类定义属性和方法

  233. 让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。
    9.3.4 重写父类的方法

  234. 对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。

  235. 使用继承时,可让子类保留从父类那里继承而来的精华,并剔除不需要的糟粕。
    9.3.5 将实例用作属性

  236. 将大型类拆分成多个协同工作的小类。
    9.3.6 模拟实物

  237. 你考虑的不是Python,而是如何使用代码来表示实物。到达这种境界后,你经常会发现,现实世界的建模方法并没有对错之分。有些方法的效率更高,但要找出效率最高的表示法, 需要经过一定的实践。

  238. 习题:冰淇淋小店:冰淇淋小店是一种特殊的餐馆。编写一个名为 IceCreamStand 的类,让它继承你为完成练习 9-1 或练习 9-4 而编写的 Restaurant 类。这两个版本的Restaurant 类都可以,挑选你更喜欢的那个即可。添加一个名为 flavors 的属性,用于存储一个由各种口味的冰淇淋组成的列表。编写一个显示这些冰淇淋的方法。创建一个IceCreamStand 实例,并调用这个方法。
    本题答案
    9.4 导入类

  239. Python允许你将类存储在模块中,然后在主程序中导入所需的模块。
    9.4.1 导入单个类

  240. 导入类是一种有效的编程方式。这还能让你将大部分逻辑存储在独立的文件中;确定类像你希望的那样工作后,你就可以不管这些文件,而专注于主程序的高级逻辑了。
    9.4.4 导入整个模块

  241. 你还可以导入整个模块,再使用句点表示法访问需要的类。

  242. 由于创建类实例的代码都包含模块名,因此不会与当前文件使用的任何名称发生冲突。
    9.4.5 导入模块中的所有类

  243. 要导入模块中的每个类,可使用下面的语法:
    from module_name import *

  244. 不推荐使用这种导入方式。
    9.4.6 在一个模块中导入另一个模块

  245. 将类存储在多个模块中时,你可能会发现一个模块中的类依赖于另一个模块中的类。在这种情况下,可在前一个模块中导入必要的类。
    9.4.7 自定义工作流程

  246. 正如你看到的,在组织大型项目的代码方面,Python提供了很多选项。熟悉所有这些选项很重要,这样你才能确定哪种项目组织方式是最佳的,并能理解别人开发的项目。
    9.5 Python 标准库

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

  248. 字典让你能够将信息关联起来,但它们不记录你添加键 — 值对的顺序。要创建字典并记录其中的键 — 值对的添加顺序,可使用模块 collections 中的 OrderedDict 类。 OrderedDict 实例的行为几乎与字典相同,区别只在于记录了键 — 值对的添加顺序。

  249. 注意 你还可以从其他地方下载外部模块。本书第二部分的每个项目都需要使用外部模块,届时你将看到很多这样的示例。
    9.6 类编码风格

  250. 你必须熟悉有些与类相关的编码风格问题,在你编写的程序较复杂时尤其如此。

  251. 类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。

  252. 对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。

  253. 可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。

  254. 需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的 import 语句,再添加一个空行,然后编写导入你自己编写的模块的 import 语句。在包含多条 import 语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何方。
    第十章:文件和异常
    10.1 从文件中读取数据

  255. 文本文件可存储的数据量多得难以置信:天气数据、交通数据、社会经济数据、文学作品等。每当需要分析或修改存储在文件中的信息时,读取文件都很有用,对数据分析应用程序来说尤其如此。
    10.1.1 读取整个文件

  256. 要读取文件,需要一个包含几行文本的文件。

  257. 要以任何方式使用文件——哪怕仅仅是打印其内容,都得先打开文件,这样才能访问它。函数 open() 接受一个参数:要打开的文件的名称。

  258. 相比于原始文件,该输出唯一不同的地方是末尾多了一个空行。因为 read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行。要删
    除多出来的空行,可在 print 语句中使用 rstrip()。
    10.1.2 文件路径

  259. 要让Python打开不与程序文件位于同一个目录中的文件,需要提供文件路径,它让Python到系统的特定位置去查找。

  260. 由于文件夹text_files位于文件夹python_work中,因此可使用相对文件路径来打开该文件夹中的文件。相对文件路径让Python到指定的位置去查找,而该位置是相对于当前运行的程序所在目录的。

  261. 在Windows系统中,在文件路径中使用反斜杠( \ )而不是斜杠( / )。
    with open(‘text_files\ filename .txt’) as file_object:

  262. 你还可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方了。这称为绝对文件路径。

  263. 在Windows系统中,它们类似于下面这样:
    file_path = ‘C:\Users\ehmatthes\other_files\text_files\ filename .txt’
    with open(file_path) as file_object:

  264. 注意 Windows系统有时能够正确地解读文件路径中的斜杠。如果你使用的是Windows系统,且结果不符合预期,请确保在文件路径中使用的是反斜杠。
    10.1.3 逐行读取

  265. 读取文件时,常常需要检查其中的每一行:你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。

  266. 要以每次一行的方式检查文件,可对文件对象使用 for 循环。
    10.1.4 创建一个包含文件各行内容的列表

  267. 使用关键字 with 时, open() 返回的文件对象只在 with 代码块内可用。如果要在 with 代码块外访问文件的内容,可在 with 代码块内将文件的各行存储在一个列表中,并在 with 代码块外使用该列表:你可以立即处理文件的各个部分,也可推迟到程序后面再处理。
    10.1.5 使用文件的内容

  268. 将文件读取到内存中后,就可以以任何方式使用这些数据了。

  269. 注意 读取文本文件时,Python将其中的所有文本都解读为字符串。如果你读取的是数字,并要将其作为数值使用,就必须使用函数 int() 将其转换为整数,或使用函数 float() 将其转换为浮点数。

  270. 对于你可处理的数据量,Python没有任何限制;只要系统的内存足够多,你想处理多少数据都可以。
    10.2 写入文件

  271. 保存数据的最简单的方式之一是将其写入到文件中。
    10.2.1 写入空文件

  272. 要将文本写入文件,你在调用 open() 时需要提供另一个实参,告诉Python你要写入打开的文件。

  273. 指定读取模式( ‘r’ )、写入模式( ‘w’ )、附加模式( ‘a’ )或让你能够读取和写入文件的模式( ‘r+’ )。

  274. 如果你省略了模式实参,Python将以默认的只读模式打开文件。

  275. 相比于你的计算机中的其他文件,这个文件没有什么不同。你可以打开它、在其中输入新文本、复制其内容、将内容粘贴到其中等。

  276. 注意 Python只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数str() 将其转换为字符串格式。
    10.2.2 写入多行

  277. 要让每个字符串都单独占一行,需要在 write() 语句中包含换行符。

  278. 像显示到终端的输出一样,还可以使用空格、制表符和空行来设置这些输出的格式。
    10.2.3 附加到文件

  279. 如果你要给文件添加内容,而不是覆盖原有的内容,可以附加模式打开文件。

  280. 你以附加模式
    打开文件时,Python不会在返回文件对象前清空文件,而你写入到文件的行都将添加到文件末尾。如果指定的文件不存在,Python将为你创建一个空文件。
    10.3 异常

  281. Python使用被称为异常的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,它都会创建一个异常对象。

  282. 异常是使用 try-except 代码块处理的。 try-except 代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。使用了 try-except 代码块时,即便出现异常,程序也将继续运行:显示你编写的友好的错误消息,而不是令用户迷惑traceback。
    10.3.2 使用 try-except 代码块

  283. 当你认为可能发生了错误时,可编写一个 try-except 代码块来处理可能引发的异常。
    10.3.4 else 代码块

  284. 通过预测可能发生错误的代码,可编写健壮的程序,它们即便面临无效数据或缺少资源,也能继续运行,从而能够抵御无意的用户错误和恶意的攻击。
    10.3.5 处理 FileNotFoundError 异常

  285. 你要查找的文件可能在其他地方、文件名可能不正确或者这个文件根本就不存在。对于所有这些情形,都可使用 try-except 代码块以直观的方式进行处理。
    10.3.6 分析文本

  286. 方法 split() 以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。
    10.3.8 失败时一声不吭

  287. 要让程序在失败时一声不吭,可像通常那样编写 try 代码块,但在 except 代码块中明确地告诉Python什么都不要做。Python有一个 pass 语句,可在代码块中使用它来让Python什么都不要做。

  288. pass 语句还充当了占位符,它提醒你在程序的某个地方什么都没有做,并且以后也许要在这里做些什么。
    10.4 存储数据

  289. 一种简单的方式是使用模块 json 来存储数据。

  290. 模块 json 让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。你还可以使用 json 在Python程序之间分享数据。更重要的是,JSON数据格式并非Python专用的,这让你能够将以JSON格式存储的数据与使用其他编程语言的人分享。

  291. 注意 JSON(JavaScript Object Notation)格式最初是为JavaScript开发的,但随后成了一种常见格式,被包括Python在内的众多语言采用。
    10.4.1 使用 json.dump() 和 json.load()

  292. 函数 json.dump() 接受两个实参:要存储的数据以及可用于存储数据的文件对象。
    10.4.2 保存和读取用户生成的数据

  293. 用户首次运行这个程序时,文件username.json不存在,将引发FileNotFoundError 异常,因此Python将执行 except 代码块:提示用户输入其用户名
    ,再使用 json.dump() 存储该用户名,并打印一句问候语。
    10.4.3 重构

  294. 代码能够正确地运行,但可做进一步的改进——将代码划分为一系列完成具体工作的函数。这样的过程被称为重构。重构让代码更清晰、更易于理解、更容易扩展。

  295. 将没有存储用户名时提示用户输入的代码放在一个独立的函数中。

更多推荐

【学习注意事项】Python编程:从入门到实践