一、函数
1、定义函数
在Python中创建一个函数,需要选择函数名,并定义其参数、行为和返回值。
在def关键字后面,指定函数的名称,名称选择遵循与变量名相同的规则。按惯例,函数名不应使用大写字母,单词用下划线分隔:like_this。
在Python中,可以使用语法“[函数名]([逗号分隔的参数])”来调用一个函数
函数可以有一个或多个参数,也可以不接受任何参数
函数必须包含return语句。如果函数没有return语句,则会返回None
2、内置函数
Python编程语言中自带了一个被称为内置函数(builtin function)的函数库
其中的部分函数:len也是一个内置函数,表示返回对象的长度,如字符串的长度
内置函数str接受一个对象作为参数,并返回一个数据类型为str的新对象
int函数可接受一个对象作为参数,并返回一个整型对象
float函数可接受一个对象作为参数,并返回一个浮点数对象
3、复用函数
函数不仅可用于计算并返回值,还可以封装我们希望复用的功能
4、必选及可选参数
函数可接受两种参数。一种是必选参数,(requiredparameter)。当用户调用函数时,必须传入所有必选参数,否则Python将报告异常错误。
Python中还有另一种参数,即可选参数(optional parameter)。函数只在需要时才会传入,并不是执行程序所必须的。如果没有传入可选参数,函数将使用其默认值
使用如下语法定义可选参数:[函数名]([参数名]=[参数值])。与必选参数一样,可选参数也得使用逗号分隔。一个带可选参数的函数示例如下:
你可以定义一个既有必选参数也有可选参数的函数,但是必选参数必须位于可选参数之前。
参数可以传递的数据类型:
- 传递列表:函数传递列表很有用,这种列表包含的可能是名字、数字或更复杂的对象(如字典)。将列表传递给函数后,函数就能直接访问其内容。
- 在函数中修改列表:将列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永久性的,这让你能够高效地处理大量的数据。
- 禁止函数修改列表:可向函数传递列表的副本而不是原件;这样函数所做的任何修改都只影响副本,而丝毫不影响原件。要将列表的副本传递给函数,可以像下面这样做
切片表示法[:]创建列表的副本
- 传递任意数量的实参:Python允许函数从调用语句中收集任意数量的实参,在函数的形参前面 添加一个星号例如: *toppings,形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。注意,Python将实参封装到一个元组中,即便函数只收到一个值也是如此。
- 结合使用位置实参和任意数量实参:要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。示例如下:
前面的函数还需要一个表示比萨尺寸的实参,必须将该形参放在形参*toppings的前面,述函数定义,Python将收到的第一个值存 储在形参size中,并将其他的所有值都存储在元组toppings中。在函数调用中,首先指定表示比萨尺寸的实参,然后根据需要指定任意数量的配料。
- 使用任意数量的关键字实参:如果需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键—值对——调用语句提供了多少就接受多少。示例如下:
def build_profile(first, last, **user_info): #形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所有名称—值对都封装到这个字典中,在这个函数中,可以像访问其他字典那样访问user_info中的名称—值对 profile = {} #创建了一个名为profile的空字典,用于存储用户简介 profile["first_name"] = first #将名和姓加入到这个字典中,因为我们总是会从用户那里收到这两项信息 profile["last_name"] = last for key, value in user_info.items(): #遍历字典user_info中的键—值对,并将每个键—值对都加入到字典profile中。最后,将字典profile返回给函数调用 profile[key] = value return profile build_profile("albert", "einstein", location="princeton", field="physics") print(build_profile("albert", "einstein", location="princeton", field="physics"))
4、作用域
变量有一个很重要的属性,作用域(scope),变量的作用域由其定义在程序中所处的位置决定。
如果在函数(或类,本书第二部分将介绍)之外定义了一个变量,则变量拥有全局作用域(global scope):即在程序中任意地方都可以对其进行读写操作。带有全局作用域的变量,被称为全局变量(global variable)。如果在函数(或类)内部定义一个变量,则变量拥有局部作用域(local scope):即程序只有在定义该变量的函数内部才可对其进行读写。
在定义变量的函数之外使用变量,相当于使用一个尚未定义的变量
可以在程序的任何地方对全局变量进行写操作,但是在局部作用域中需稍加注意:必须明确使用global关键字,并在其后写上希望修改的变量
5、异常处理
依赖input函数获得用户输入,则意味着无法控制程序的输入(用户提供的输入可能会导致错误)
异常处理使用try和except关键字,在你修改程序使用异常处理之后,如果用户输入,程序不会报错,而是会打印一段话告诉用户。
Python中的每一个异常都是一个对象
try从句包含可能会发生的错误,except从句包含仅在错误发生时执行的代码
面是在程序中进行异常处理的一个示例,这样如果用户输入0作为第二个数字,程序也不会崩溃。示例如下:
在except关键字后添加圆括号,并用逗号分隔两个异常即可将二者捕获,示例如下:
不要在except语句中使用try语句定义的变量,因为异常可能是在变量定义之前发生的,如果在except语句中这样做可能又会导致新的异常出现,示例如下:
6、文档字符串
定义一个带参数的函数时,有时要求参数必须是某种数据类型,函数才能成功执行。那么该如何将这点告知函数的调用者?在编写函数时,在函数顶部留下注释来解释每个参数应该为何种数据类型,是比较好的做法。这些注释被称为文档字符串(docstring)
7、有需要才使用变量
只有在后面的程序中会用到数据,才有必要将其保存至变量。不要仅仅为了打印数值就将整数保存至变量,示例如下:
8、函数返回值
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。
9、函数编写指南
编写函数时,需要牢记几个细节。应给函数指定描述性名称,且只在其中使用小写字母和下划线。描述性名称可帮助你和别人明白代码想要做什么。给模块命名时也应遵循上述约定。每个函数都应包含简要地阐述其功能的注释,该注释应紧跟在函数定义后面,并采用 文档字符串格式。文档良好的函数让其他程序员只需阅读文档字符串中的描述就能够使用它:他们完全可以相信代码如描述的那样运行;只要知道函数的名称、需要的实参以及返回值的类型,就能在自己的程序中使用它。给形参指定默认值时,等号两边不要有空格, 对于函数调用中的关键字实参,也应遵循这种约定。如果形参很多,导致函数定义的长度超过了79字符,可在函数定义中输入左括号后按回车键,并在下一行按两次Tab键,从而将形参列表和只缩进一层的函数体区分开来。
二、容器:列表、元组和字典。
1、方法
函数在Python中有一个类似的概念,叫方法(method)。方法是与指定数据类型紧密相关的函数。方法与函数一样,可执行代码并返回结果。不同的是,只有在对象上才能调用方法。同样也可以传递参数给方法。
2、列表
列表(list)是以固定顺序保存对象的容器
列表用方括号表示。我们可使用两种语法创建列表,一种是使用list函数创建空列表,示例如下:
或者直接使用方括号:
使用第二种语法,并将你希望放在列表中的所有对象填入方括号中,用逗号分隔,即可创建一个包含所有对象的列表
这里可使用append方法向列表中添加一个新元素,示例如下:
但append方法永远是将新元素添加至列表的末尾。
字符串、列表和元组都是可迭代的(iterable)。如果可以使用循环访问对象中的每一个元素,那么该对象是可迭代的,被称为可迭代对象。可迭代对象中的每一个元素都有一个索引(index),即表示元素在可迭代对象中位置的数字。列表中第一个元素的索引是0,而不是1。
你可以使用语法[列表名][[索引]]获取一个元素,如果获取的是不存在的索引,Python会报告异常。
列表是可变的(mutable)。如果一个容器是可变的,则可以向该容器中增删对象。将列表中某个元素的索引赋给一个新的对象,即可改变该元素,你可以使用加法操作符来合并两个列表,也可以使用关键字in检查某个元素是否在列表中,使用关键字not检查某个元素是否不在列表中,使用函数len可获得列表的大小(包含元素的个数)。
3、元组
元组(tuple)是存储有序对象的一种容器。与列表不同,元组是不可变的(immutable),这意味着其内容不会变化。创建元组后,无法修改其中任何元组的值,也无法添加或修改元素。用圆括号表示元组,且必须用逗号分隔元组中的元素。有两种语法可以创建元组,第一种如下所示:
如果要向元组中新增对象,可用第二种语法创建一个新的元组,并在其中加入你希望增加的每个元素,用逗号分隔:
即使元组中只有一个元素,也需要在该元素的后面加上逗号。只有这样,Python才能将其与其他为了表示运算顺序而放在圆括号中的数字标记进行区分。创建元组之后,不能再新增元素或修改已有元素。如果在创建元组后这样做,Python会报告异常。可使用与列表一样的方法来获取元组的元素,即引用其索引。(因为在处理明确永远不会改变的,并且也不希望其他程序对其进行修改的值时,元组是非常有用的。地理坐标就是适合使用元组存储的一种数据。城市的经纬度应保存在元组中,因为这些值永远不会改变,保存为元组意味着程序不会意外对其进行修改)
4、字典
字典(dictionary)是另一种用于存储对象的内置容器。它们被用来链接键(key)和值(value)这两个对象(如图5-2所示)。将一个对象链接至另一个对象,也被称为映射(mapping),结果为产生一个键值对(key-value pair)。可将键值对添加到字典,然后使用键在字典中查询,可获得其对应的值。但是无法使用值来查询键。
字典是可变的,因此可以向字典中新增键值对。与列表和元组不同,字典中存储的对象是无序的,字典的价值在于键与值之间的关联。
字典用花括号表示。有两种创建字典的语法,其一如下:
上述两种语法都要求用冒号分隔键与值,每个键值对之间用逗号分隔。与元组不同的是,如果只有一个键值对,不需要在其后添加逗号。
字典的键是无序的,需要输出时Python会随机打印其元素。字典是可变的。创建字典后,可通过语法“[字典名][[键]] = [值]”添加新的键值对,并通过语法“[字典名][[键]]”查找值。字典的值可以是任意对象,但是字典的键必须是不可变的。字符串或元组可以用作字典的键,但是列表或字典不可以。
可以使用关键字in检查某个键是否在字典中,但不能用其检查某个值是否在字典中,如果访问一个不在字典中的键,Python将报告异常。在关键字in之前加上关键字not,可检查键是否不在字典中,可使用关键字del删除字典中的键值对。
5、容器嵌套容器
可以在列表中保存列表,也可以在列表中存储元组,在元组中存储列表,还可以在列表或元组中存储字典。列表、字典或元组都可以成为字典中的值。
6、字符串操作
Python自带操作字符串的功能, 如果字符串跨越一行以上,可以使用三引号。
与列表和元组一样,字符串也是可迭代的。可使用索引查找字符串中的每个字符。与其他可迭代对象一样,字符串中第一个字符所在的索引为0,其后每个索引递增1。Python还支持使用负索引(negative index)查找列表中的元素:可用来从右向左查找可迭代对象中元素的索引(必须是一个负数)。使用索引-1可以查找可迭代对象中的最后一个元素。负索引-2查找的是倒数第二个元素,负索引-3查找的是倒数第三个元素,以此类推。
字符串和元组一样都是不可变的,无法修改字符串中的字符。如果想要修改,就必须创建一个新的字符串。
Python提供了多个从已有字符串中创建新字符串的方法:
字符串拼接:使用加法操作符,将两个或多个字符串组合在一起,结果就是由第一个字符串中的字符和其他字符串中的字符共同构成的一个新字符串。
字符串乘法:可使用乘法操作符,将字符串与数字相乘。
改变大小写:可使用字符串的upper方法,将字符串中的每个字符改为大写。示例如下
类似地,可使用字符串的lower方法将字符串中的每个字符改为小写,还可使用字符串的capitalize方法,将字符串的首字母改为大写。
格式化:可使用format方法创建新字符串,该方法会把字符串中的“{}”替换为传入的字符串:
也可以把变量作为参数传递:
花括号可重复使用:
如果要根据用户输入来创建字符串,format方法很有用。
7、分割
字符串有一个叫split的方法,可用来将字符串分割为两个或多个字符串。需要传入一个字符串作为split方法的参数,并用其将原字符串分割为多个字符串。
8、连接
join方法可以在字符串的每个字符间添加新字符:
也可以在空字符串上调用join方法,传入一个字符串列表作为参数,从而将这些字符串连接为一个单一字符串:
还可以在包含空格符的字符串上,调用join方法,创建一个所有单词均由空格符分隔的字符串:
9、去除空格
可使用strip方法去除字符串开头和末尾的空白字符
10、替换
在replace方法中,第一个参数是要被替换的字符串,第二个参数是用来替换的字符串。
11、查找索引
可使用index方法,获得字符串中某个字符第一次出现的索引。(注意是第一次出现),如果index方法没有找到匹配的结果,Python会报告异常错误,如果不确定是否有匹配的结果,可使用如下异常处理的方法
12、in关键字
关键字in可检查某个字符串是否在另一个字符串中,返回结果为True或False,在in前面加上关键字not,即可检查某个字符串是否不在另一个字符串中
13、字符串转义
字符串转义(escaping),指的是在Python中有特殊意义的字符(上例中为双引号)前加上一个符号,告诉Python在本例中该符号代表的是一个字符,而没有特殊意义。在Python中用反斜杠进行转义。
如果在字符串中使用单引号,而非双引号,则不需要进行转义,还可以在单引号中使用双引号,这比对双引号进行转义更加简单。
14、 切片
切片(slicing)可将一个可迭代对象中元素的子集,创建为一个新的可迭代对象。切片的语法是[可迭代对象][[起始索引:结束索引]]。起始索引(start index)是开始切片的索引,结束索引(end index)是结束索引的位置。切片时包含起始索引位置的元素,但不包括结束索引位置的元素。果起始索引是0,那么可以将起始索引的位置留空,如果结束索引是可迭代对象中最后一个元素的索引,那么可以将结束索引的位置留空。
四、循环
1、for 循环:一种用来遍历可迭代对象的循环。这个过程被称为遍历(iterating)
可使用语法"for [变量名] in [可迭代对象名]: [指令]"定义for循环,其中[变量名]是计划赋给可迭代对象中每个元素值的变量名称,[指令]是每次循环要执行的代码。
下面是使用for循环遍历列表元素的示例:
可以使用for循环修改可变且可迭代对象中的元素:
(上例中使用for循环遍历了列表tv,并通过一个索引变量(indexvariable)跟踪列表内当前的元素。索引变量是代表可迭代对象中索引的一个整数,起始值为0,每循环一次索引变量的值递增一个。可以通过索引变量来获取列表中当前的元素,保存在变量new中。然后对new调用upper方法并保存结果,再用索引变量替换列表中的当前元素)
由于访问可迭代对象中索引和元素是很常见的操作,Python提供了一个专门的语法:
(上例中没有遍历tv列表,而是将其调给了enumerate函数去遍历该函数返回的结果。enumerate函数会返回一个对应当前元素索引的值,可保存在变量i中。)
还可以使用for循环在可变可迭代对象之间传递数据。例如,使用两个for循环获取两个不同列表中的所有字符串,然后将每个字符大写,并放入一个新的列表中。
2、range函数
内置的range函数创建一个整数序列,然后通过for循环遍历。range函数接受两个参数:序列起始数字和结束数字,返回的整数序列包含从第一个参数到第二个参数之间(不含第二个参数)的所有整数
3、while循环
while 循环:它是一种只要表达式的值为True就一直执行代码的循环。while循环的语法是“while [表达式]: [执行代码]”,其中“[表达式]”是决定循环是否继续进行的表达式,“[执行代码]”则是只要循环继续就执行的代码。
如果你定义的while循环的表达式求值永远为True,循环将不会停止执行。一个不会停止执行的循环也被称为死循环(infinite loop)。(可以按Ctrl+c强制终止死循环)
4、break语句
可使用break语句(带关键字break的语句)来终止循环。
5、continue语句
可使用continue语句(带关键字continue的语句)来终止循环的当前迭代,并进入下一次迭代。
6、嵌套循环
可以通过多种方式对循环进行组合。例如,可以在一个循环里加入另一个循环,甚至在加入的循环里再加一个循环。循环中可嵌套的循环数量没有限制,但是最好要控制数量不要过多。当一个循环位于另一个循环之内时,它就是嵌套在第一个循环中。这种情况下,内部包含一个循环的循环称为外循环(outer loop),嵌套的循环称为内循环(inner loop)。当存在嵌套循环时,外循环每遍历一次,内循环就遍历一次其可迭代对象中的所有元素。示例如下:
五、模块
程序员将大型程序分割成多个包含Python代码的文件,也被称为模块(module)。Python支持在一个模块中使用另一个模块内的代码。Python还有内置模块(builtin module),它是Python语言自带的,包含了许多重要的功能。
1、导入内置模块
使用模块之前,必须先导入(import):意味着要写代码,以便让Python知道从哪获取模块。可使用语法import [模块名]导入模块,将[模块名]替换为希望导入模块的名字。导入模块之后,即可使用其中的变量和函数。
导入模块之后,可通过语法[模块名].[代码]使用其中的代码,将[模块名]替换为已导入模块的名称,[代码]替换为希望使用的函数或变量的名称。
random是一个内置模块。可使用其中一个叫randint的函数生成一个随机整数:传入两个整数,函数返回两者之间的一个随机整数。
可使用内置模块statistics计算由数字组成的可迭代对象的均值、中间值和众数(mode)。
可使用内置模块keyword检查字符串是不是Python关键字。
2、导入其他模块
我们可以创建一个模块,然后在另一个模块中导入该模块并使用其中的代码。首先,在计算机上创建一个名为tstp的新文件夹。在文件夹中,新建一个名为hello.py的文件。在tstp文件夹中,再新建一个名为project.py的文件,在project.py可以将hello.py作为模块导入,导入模块时,其中的代码都会被执行。
这个行为有时候会导致不便。比如你的模块中可能有测试代码,不希望在导入时执行。那么将模块中所有的代码放置在if __name__ == "__main__"语句中,即可解决该问题。如下示例:
六、文件
我们可以使用Python处理文件。例如,可使用Python读取或写文件数据。读取(reading)文件数据指的是访问文件中的数据。向文件中写(writing)数据指的是添加或修改文件中的数据
1、写文件操作、
处理文件的第一步是使用Python内置的open函数打开文件。open函数有两个参数:一个代表要打开文件路径的字符串,另一个代表打开文件的模式。
为了避免程序在不同操作系统中运行出错,应使用内置的os模块来创建文件路径。模块中的path函数接受文件路径中的文件夹名作为参数,并自动构建完整的文件路径。示例如下:
使用path函数创建文件路径,可以确保其在任何操作系统中都可以正常运行。但是在处理文件路径时还是容易出现问题。
传入open函数的参数模式,决定了对打开的文件执行什么操作。以下是支持的文件打开模式。•"r"以只读模式打开文件。•"w"以只写模式打开文件,'a+' (可追加可写,文件若不存在就创建)。如果文件已存在,会覆盖文件。如果文件不存在,则会创建一个新文件。•"w+"以可读可写模式打开文件。如果文件已存在,会覆盖原文件。如果文件不存在,则创建一个新文件进行读写操作。open函数会返回一个叫文件对象(file object)的对象,可用来读/写文件。使用"w"模式时,如果没有现存文件,open函数会在运行程序的目录中创建一个新文件。然后,可使用文件对象的write方法写入文件,并通过close方法关闭文件。如果使用了open函数打开文件,就必须要通过close方法关闭。如果你使用open函数打开了多个文件但又忘记关闭。
2、自动关闭文件
有一种我们更推荐使用的文件打开方法,可以避免忘记关闭文件。如果使用该方法,要将所有需要访问的文件对象的代码写在with语句之中:一种复合语句,Python在执行完该语句时会自动执行下一个的行为。使用with语句打开文件的语法是“with open([文件路径], [模式]) as [变量名]: [执行代码]”。[文件路径]代表文件所在的位置,[模式]代表以何种模式打开文件,[变量名]代表文件对象被赋予的变量名,[执行代码]则是需要访问文件对象变量的代码。
在使用上述语法打开文件时,会在[执行代码]运行完毕后自动关闭文件。下面是使用新语法读、写、关闭文件的示例:
3、读取文件
- 如果要读取文件,可传入"r"作为open函数的第二个参数。然后调用文件对象的read方法,会返回一个包含文件所有行的可迭代对象。
在没有关闭又重新打开文件的情况下,你只能调用文件对象的read方法一次。因此,如果后续程序需要,应该将文件内容保存在一个变量或容器中。下面是将的文件内容保存在列表中的示例:
- 如果要用一个with一句同时读取多个文件,示例如下:
username_list = [] password_list = [] ip_list = [] with open("username.txt", "r") as file1, open("password.txt", "r") as file2, open("ip.txt", "r") as file3: for line1, line2, line3 in zip(file1.readlines(), file2.readlines(), file3.readlines()): username = line1.strip() username_list.append(username) password = line2.strip() password_list.append(password) ip = line3.strip() ip_list.append(ip) print(username_list) print(password_list) print(ip_list)
4、CSV文件
Python有一个内置模块支持处理CSV文件(CSV file)。CSV文件的后缀为.csv,它使用英文逗号来分隔数据(CSV是逗号分隔值的英文简称)。需要管理如Excel等报表软件的程序员经常使用CSV文件。CSV文件中用逗号分隔的每个数据代表报表中的一个单元格,每行代表一个报表行。分隔符(delimiter)是CSV文件中用来分隔数据的符号,如逗号或竖线“|”。
也可使用with语句打开CSV文件,但是在语句中需要使用csv模块将文件对象转化成csv对象。csv模块有一个叫writer的方法,可接受一个文件对象和一个分隔符。writer方法返回一个带writerow方法的csv对象。writerow方法接受一个列表作为参数,可用来向CSV文件写入数据。列表中的每个元素都会被写入,并传入writer方法的分隔符来分隔。writerow方法只创建一行数据,因此要创建两行数据必须调用该方法两次。示例如下:
还可以使用csv模块读取文件的内容。在读取CSV文件的内容之前,首先传入"r"作为open函数的第二个参数,然后在with语句中调用reader方法,传入文件对象并以逗号作为分隔符,这会返回一个可迭代对象,可用来访问文件中的每行数据。示例如下:
(本例中打开了st.csv文件以用于读取数据,并使用reader方法将文件对象转换为了csv对象。然后使用循环遍历csv对象。每次循环时,调用逗号字符串的join方法,在文件每行数据的中间添加逗号,并打印其在原文件中的样子(由逗号分隔)。)
*********************************************************************************************分割************************************************************************************
七、使用pip和虚拟环境安装软件包
1、 创建虚拟环境
用于创建和管理虚拟环境的模块称为 venv
。venv
通常会安装你可用的最新版本的 Python。如果您的系统上有多个版本的 Python,您可以通过运行 python3
或您想要的任何版本来选择特定的Python版本。
要创建虚拟环境,请确定要放置它的目录,并将 venv
模块作为脚本运行目录路径:
python3 -m venv tutorial-env
如果 tutorial-env
目录不存在,它将为你创建一个,并在其中创建包含Python解释器,标准库和各种支持文件的副本的目录。
虚拟环境的常用目录位置是 .venv
。 这个名称通常会令该目录在你的终端中保持隐藏,从而避免需要对所在目录进行额外解释的一般名称。 它还能防止与某些工具所支持的 .env
环境变量定义文件发生冲突。
创建虚拟环境后,您可以激活它。
在Windows上,运行:
tutorial-envScriptsactivate.bat