1.2 Python语法基础
1.2.1 Python数据类型
计算机程序不仅可以处理各种数值,还可以处理文本、图形、音频、视频、网页等各种各样的数据。对于不同类型的数据,需要定义不同的数据类型进行处理。
1. 数值类型
Python数值类型用于存储数值。Python支持以下几种数值类型。
• 整型(int):通常被称为是整型或整数,是正或负整数,不带小数点。在Python3里,只有一种整数类型int,没有Python 2.x中的Long。
• 浮点型(float):浮点型数值由整数部分与小数部分组成,浮点型数值也可以使用科学计数法表示(2.78e2就是2.78 × 102 = 278)。
• 复数(complex):复数由实数部分和虚数部分构成,可以用a+bj或者complex(a,b)表示,复数的虚部以字母j或J结尾,例如,2+3j。
数据类型是不允许改变的,这就意味着如果改变数值数据类型的值,将重新分配内存空间。
2. 字符串
字符串是Python中最常用的数据类型。我们可以使用引号来创建字符串。Python不支持字符类型,单字符在Python也是作为一个字符串使用。Python使用单引号和双引号来表示字符串,效果是一样的。
3. 布尔类型
Python支持布尔类型的数据,布尔类型只有True和False两种值,但是布尔类型有以下几种运算。
(1)and(与)运算:只有两个布尔值都为True时,计算结果才为True。
True and True #结果是 True True and False #结果是 False False and True #结果是 False False and False #结果是 False
(2)or(或)运算:只要有一个布尔值为True,计算结果就为True。
True or True #结果是 True True or False #结果是 True False or True #结果是 True False or False #结果是 False
(3)not(非)运算:把True变为False,或者把False变为True:
not True #结果是 False not False #结果是 True
布尔运算在计算机中用来做条件判断,根据计算结果为True或者False,计算机可以自动执行不同的后续代码。
在Python中,布尔类型还可以与其他数据类型做and、or和not运算,这时下面的几种情况会被认为是False:为0的数字,包括0和0.0;空字符串' '和"";表示空值的None;空集合,包括空元组()、空序列[]和空字典{};其他的值都为True。例如:
a = 'python' print (a and True) #结果是 True b = '' print (b or False) #结果是 False
4. 空值
空值是Python里一个特殊的值,用None表示。它不支持任何运算也没有任何内置函数方法。None和任何其他的数据类型比较之后只会返回False。在Python中未指定返回值的函数会自动返回None。
1.2.2 序列数据结构
数据结构是计算机存储、组织数据的方式。序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字,即它的位置或索引,第一个索引是0,第二个索引是1,以此类推。序列可以进行的操作包括索引、截取(切片)、加、乘、成员检查。此外,Python已经内置确定序列的长度以及确定最大和最小元素的方法。Python内置序列类型最常见的是列表、元组和字符串。另外,Python提供了字典和集合这样的数据结构,它们属于无顺序的数据集合体,不能通过位置索引来访问数据元素。
1. 列表
列表(list)是最常用的Python数据类型,列表的数据项不需要具有相同的类型。列表类似于其他语言的数组,但功能比数组强大得多。
创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。实例如下:
list1 = ['中国', '美国', 1997, 2000] list2 = [1, 2, 3, 4, 5 ] list3 = ["a", "b", "c", "d"]
列表索引从0开始。列表可以进行截取(切片)、组合等。
(1)访问列表中的值
使用下标索引来访问列表中的值,同样也可以使用方括号的形式截取字符,实例如下:
list1 = ['中国', '美国', 1997, 2000] list2 = [1, 2, 3, 4, 5, 6, 7 ] print ("list1[0]: ", list1[0] ) print ("list2[1:5]: ", list2[1:5] )
以上实例输出结果如下:
list1[0]: 中国 list2[1:5]: [2, 3, 4, 5]
(2)更新列表
可以对列表的数据项进行修改或更新,实例如下:
list = ['中国', 'chemistry', 1997, 2000] print ( "Value available at index 2 : ") print (list[2] ) list[2] = 2001 print ( "New value available at index 2 : ") print (list[2] )
以上实例输出结果如下:
Value available at index 2 : 1997 New value available at index 2 : 2001
(3)删除列表元素
方法一:使用del语句来删除列表中的元素,实例如下:
list1 = ['中国', '美国', 1997, 2000] print (list1) del list1[2] print ("After deleting value at index 2 : ") print (list1)
以上实例输出结果如下:
['中国', '美国', 1997, 2000] After deleting value at index 2 : ['中国', '美国', 2000]
方法二:使用remove()方法来删除列表的元素,实例如下:
ist1 = ['中国', '美国', 1997, 2000] list1.remove(1997) list1.remove('美国') print(list1)
以上实例输出结果如下:
['中国', 2000]
方法三:使用pop()方法来删除列表的指定位置的元素,无参数时删除最后一个元素,实例如下:
list1 = ['中国', '美国', 1997, 2000] list1.pop(2) #删除位置2元素1997 list1.pop() #删除最后一个元素2000 print (list1)
以上实例输出结果如下:
['中国', '美国']
(4)添加列表元素
可以使用append()方法在列表末尾添加元素,实例如下:
list1 = ['中国', '美国', 1997, 2000] list1.append(2003) print (list1)
以上实例输出结果如下:
['中国', '美国', 1997, 2000, 2003]
(5)定义多维列表
可以将多维列表视为列表的嵌套,即多维列表的元素值也是一个列表,只是维度比父列表小1。二维列表(即其他语言的二维数组)的元素值是一维列表,三维列表的元素值是二维列表。例如,定义一个二维列表。
list2 = [["CPU", "内存"], ["硬盘","声卡"]]
二维列表比一维列表多一个索引,可以使用如下方法获取元素:
列表名[索引1][索引2]
例如:定义3行6列的二维列表,打印出元素值。
rows=3 cols=6 matrix = [[0 for col in range(cols)] for row in range(rows)] #列表生成式生成二维列表 for i in range(rows): for j in range(cols): matrix[i][j]=i*3+j print (matrix[i][j],end=",") print ('\n')
以上实例输出结果如下:
0,1,2,3,4,5, 3,4,5,6,7,8, 6,7,8,9,10,11,
列表生成式(List Comprehensions)是Python内置的一种功能强大的生成列表的表达式。如果要生成一个list [1, 2, 3, 4, 5, 6, 7, 8,9],则可以用range(1, 10):
>>> L= list(range(1, 10)) #L是[1, 2, 3, 4, 5, 6, 7, 8, 9]
如果要生成[1×1, 2×2, 3×3, …, 10×10],则可以使用如下循环:
>>> L= [] >>> for x in range(1 , 10): L.append(x*x) >>> L [1, 4, 9, 16, 25, 36, 49, 64, 81]
列表生成式还可以用以下语句代替以上的烦琐循环来完成:
>>> [x*x for x in range(1, 11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
列表生成式的书写格式:把要生成的元素x×x放到前面,后面设置for循环。这样就可以把list创建出来。for循环后面还可以加上if判断,例如,如下代码可筛选出偶数的平方:
>>> [x*x for x in range(1 , 11) if x%2 == 0] [4, 16, 36, 64, 100]
再如,把一个list列表中所有的字符串变成小写形式:
>>> L = ['Hello', 'World', 'IBM', 'Apple'] >>> [s.lower() for s in L] ['hello', 'world', 'ibm', 'apple']
当然,列表生成式也可以使用两层循环,例如,生成'ABC'和'XYZ'中字母的全部组合:
>>> print([m + n for m in 'ABC' for n in 'XYZ']) ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
for循环其实可以同时使用两个甚至多个变量,例如,字典(Dict)的items()可以同时迭代key和value:
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' } #字典 >>> for k, v in d.items(): print(k, '键=', v, endl=’;’)
程序运行结果:
y 键= B; x 键= A; z 键= C;
因此,列表生成式也可以使用两个变量来生成list列表:
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' } >>> [k + '=' + v for k, v in d.items()] ['y=B', 'x=A', 'z=C']
2. 元组
Python的元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组使用小括号“()”,列表使用方括号“[]”。元组中的元素类型也可以不相同。
(1)创建元组
元组的创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。实例如下:
tup1 = ('中国', '美国', 1997, 2000) tup2 = (1, 2, 3, 4, 5 ) tup3 = "a", "b", "c", "d"
tup1 =('中国', '美国', 1997, 2000)
如果创建空元组,只需写一个空括号即可。
tup1 =()
当元组中只包含一个元素时,则需要在第一个元素后面添加逗号。
tup1 =(50,)
元组与字符串类似,下标索引从0开始,可以进行截取、组合等。
(2)访问元组
元组可以使用下标索引来访问元组中的值,实例如下:
tup1 = ('中国', '美国', 1997, 2000) tup2 = (1, 2, 3, 4, 5, 6, 7 ) print ("tup1[0]: ", tup1[0]) #输出元组的第一个元素 print ("tup2[1:5]: ", tup2[1:5]) #切片,输出从第二个元素开始到第五个元素 print (tup2[2:]) #切片,输出从第三个元素开始的所有元素 print (tup2 * 2) #输出元组两次
以上实例输出结果:
tup1[0]: 中国 tup2[1:5]: (2, 3, 4, 5) (3, 4, 5, 6, 7) (1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7)
(3)元组连接
元组中的元素值是不允许修改的,但可以对元组进行连接组合,实例如下:
tup1 = (12, 34, 56) tup2 = (78, 90) #tup1[0] = 100 #修改元组元素操作是非法的 tup3 = tup1 + tup2 #连接元组,创建一个新的元组 print (tup3)
以上实例输出结果:(12, 34, 56, 78, 90)
(4)删除元组
元组中的元素值是不允许删除的,但可以使用del语句来删除整个元组,实例如下:
tup = ('中国', '美国', 1997, 2000); print (tup) del tup print ("After deleting tup : ") print(tup)
以上实例元组被删除后,输出变量会有异常信息,输出如下所示:
('中国', '美国', 1997, 2000) After deleting tup : NameError: name 'tup' is not defined
(5)元组与列表转换
因为元组值不能改变,所以可以将元组转换为列表从而可以改变数据的值。实际上列表、元组和字符串之间是可以互相转换的,但需要使用三个函数,str()、tuple()和list()。
可以使用下面的方法将元组转换为列表:
列表对象=list(元组对象)
tup=(1, 2, 3, 4, 5) list1= list(tup) #元组转为列表 print(list1) #返回[1, 2, 3, 4, 5]
可以使用以下方法将列表转换为元组:
元组对象= tuple(列表对象)
nums=[1, 3, 5, 7, 8, 13, 20] print (tuple(nums)) #列表转为元组,返回(1, 3, 5, 7, 8, 13, 20)
将列表转换成字符串如下:
nums=[1, 3, 5, 7, 8, 13, 20] str1= str(nums) #列表转为字符串,返回包含中括号及逗号的'[1, 3, 5, 7, 8, 13, 20]'字符串 print (str1[2]) #打印出逗号,因为字符串中索引号2的元素是逗号 num2=['中国', '美国', '日本', '加拿大'] str2= "%" str2= str2.join(num2) #用百分号连接起来的字符串——'中国%美国%日本%加拿大' str2= "" str2= str2.join(num2) #用空字符连接起来的字符串——'中国美国日本加拿大'
3. 字典
Python字典(dict)是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典也被称作关联数组或哈希表。
(1)创建字典
字典由键和对应值(key=>value)成对组成。字典的每个键/值对里面键和值用冒号分割,键/值对之间用逗号分割,整个字典包括在花括号中。基本语法如下:
d = {key1 : value1, key2 : value2 }
注意:键必须是唯一的,但值不必唯一。值可以取任何数据类型,但键必须是不可变的,如字符串、数字或元组。
下面是一个简单的字典实例:
dict = {'xmj' : 40, 'zhang' : 91, 'wang' : 80}
也可创建字典如下:
dict1 = { 'abc': 456 }; dict2 = { 'abc': 123, 98.6: 37 };
字典有如下特性:
① 字典值可以是任何Python对象,如字符串、数字、元组等;
② 不允许同一个键出现两次。如果创建时同一个键被赋值两次,则后一个值会覆盖前面的值;
dict = {'Name': 'xmj', 'Age': 17, 'Name': 'Manni'}; print("dict['Name']: ", dict['Name']);
以上实例输出结果:
dict['Name']: Manni
③ 键不可变,所以可以用数字、字符串或元组充当,但不能用列表,实例如下:
dict = {['Name']: 'Zara', 'Age': 7};
以上实例输出错误结果:
Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> dict = {['Name']: 'Zara', 'Age': 7} TypeError: unhashable type: 'list'
(2)访问字典里的值
访问字典里的值时把相应的键放入方括号中,实例如下:
dict = {'Name': '王海', 'Age': 17, 'Class': '计算机一班'} print ("dict['Name']: ", dict['Name']) print ("dict['Age']: ", dict['Age'])
以上实例输出结果:
dict['Name']: 王海 dict['Age']: 17
如果用字典里不存在的键访问数据,则会输出错误信息:
dict = {'Name': '王海', 'Age': 17, 'Class': '计算机一班'} print ("dict['sex']: ", dict['sex'] )
由于没有sex键,以上实例输出错误结果:
Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> print ("dict['sex']: ", dict['sex'] ) KeyError: 'sex''
(3)修改字典
向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值对,实例如下:
dict = {'Name': '王海', 'Age': 17, 'Class': '计算机一班'} dict['Age'] = 18 #更新键/值对(update existing entry) dict['School'] = "中原工学院" #增加新的键/值对(add new entry) print ("dict['Age']: ", dict['Age'] ) print ( "dict['School']: ", dict['School'];
以上实例输出结果:
dict['Age']: 18 dict['School']: 中原工学院
(4)删除字典元素
del()方法允许使用键从字典中删除元素(条目),clear()方法会清空字典所有元素。
显式删除一个字典用del命令,实例如下:
dict = {'Name': '王海', 'Age': 17, 'Class': '计算机一班'} del dict['Name'] #删除键是'Name'的元素(条目) dict.clear() #清空词典所有元素 del dict #删除词典,用del后字典不再存在
(5)in运算
字典里的in运算用于判断某键是否包含在字典里,对于value值则不适用。功能与has_key(key)方法相似。
dict = {'Name': '王海', 'Age': 17, 'Class': '计算机一班'} print ('Age' in dict ) #等价于print (dict.has_key('Age' ) )
以上实例输出结果:
True
(6)获取字典中的所有值
dict1.values( )以列表返回字典中的所有值。
dict = {'Name': '王海', 'Age': 17, 'Class': '计算机一班'} print (dict.values ())
以上实例输出结果:
[17, '王海', '计算机一班']
(7)items()方法
items()方法把字典中每对key和value组成一个元组,并把这些元组放在列表中返回。
dict = {'Name': '王海', 'Age': 17, 'Class': '计算机一班'} for key,value in dict.items(): print( key,value)
以上实例输出结果:
Name 王海 Class 计算机一班 Age 17
需要注意,字典打印出来的顺序与创建之初的顺序不同,这不是错误。字典中各个元素并没有顺序之分(因为不需要通过位置查找元素),因此,存储元素时进行了优化,使字典的存储和查询效率最高。这也是字典和列表的另一个区别:列表保持元素的相对关系,即序列关系;而字典是完全无序的,也称为非序列。如果想保持一个集合中元素的顺序,则需要使用列表,而不是字典。
4. 集合
集合(set)是一个无序不重复元素的序列。集合基本功能是进行成员关系测试和删除重复元素。
(1)创建集合
可以使用大括号({})或者set()函数创建集合,注意:创建一个空集合必须用set()而不是{ },因为{ }是用来创建一个空字典。
student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'} print(student) #输出集合,重复的元素被自动去掉
以上实例输出结果:
{'Jack', 'Rose', 'Mary', 'Jim', 'Tom'}
(2)成员测试
if('Rose' in student) : print('Rose 在集合中') else : print('Rose 不在集合中')
以上实例输出结果:
Rose 在集合中
(3)集合运算
可以使用“-”“|”“&”运算符分别进行集合的差集、并集、交集运算。
#set可以进行集合运算 a = set('abcd') b = set('cdef') print(a) print("a和b的差集:", a - b) #a和b的差集 print("a和b的并集:", a | b) #a和b的并集 print("a和b的交集:", a & b) #a和b的交集 print("a和b中不同时存在的元素:", a ^ b) #a和b中不同时存在的元素
以上实例输出结果:
{'a', 'c', 'd', 'b'} a和b的差集:{'a', 'b'} a和b的并集:{'b', 'a', 'f', 'd', 'c', 'e'} a和b的交集:{'c', 'd'} a和b中不同时存在的元素:{'a', 'e', 'f', 'b'}
1.2.3 Python控制语句
Python程序中的执行语句,默认是按照书写顺序依次执行的,此时的语句是顺序结构的。但是,仅有顺序结构还是不够的,因为有时候我们需要根据特定的情况,有选择地执行某些语句,这时我们就需要一种选择结构的语句。另外,有时候我们还可以在给定条件下反复执行某些语句,这时我们称这些语句是循环结构的。有了这三种基本的结构,我们就能够构建更加复杂的程序了。
1. 选择结构
三种基本程序结构中的选择结构,可用if语句、if…else语句和if…elif…else语句实现。
if语句是一种单选结构,它选择的是做与不做。if语句的语法形式如下所示:
if 表达式: 语句1
if语句的流程图如图1-7所示。
图1-7 if语句的流程图
而if…else语句是一种双选结构,是在两种备选行动中选择哪一个。if…else语句的语法形式如下所示:
if 表达式: 语句1 else : 语句2
if…else语句的流程图如图1-8所示。
图1-8 if…else语句的流程图
【例1-1】输入一个年份,判断其是否为闰年。闰年的年份必须满足以下两个条件之一:
(1)能被4整除,但不能被100整除的年份都是闰年;
(2)能被400整除的年份都是闰年。
分析:设变量year表示年份,判断year是否满足以下表达式。
条件(1)的逻辑表达式是:year%4 == 0&&year%100 != 0。
条件(2)的逻辑表达式是:year%400 == 0。
两者取“或”,即得到判断闰年的逻辑表达式为:
(year%4 == 0 and year%100 != 0) or year%400 == 0
程序代码:
year = int(input('输入年份:')) #输入x,input()获取的是字符串,所以需要转换 #成整型 if year%4 == 0 and year%100 != 0 or year%400 == 0: #注意运算符的优先级 print(year, "是闰年") else: print( year, "不是闰年")
判断闰年后,也可以输入某年某月某日,判断这一天是这一年的第几天。以3月5日为例,应该先把前两个月的天数加起来,然后再加上5即为本年的第几天。特殊情况是闰年,在输入月份大于3时需考虑多加一天。
程序代码:
year = int(input('year:')) #输入年 month = int(input('month:')) #输入月 day = int(input('day:')) #输入日 months = (0,31,59,90,120,151,181,212,243,273,304,334) if 0 <= month <= 12: sum = months[month - 1] else: print( '月份输入错误') sum += day leap = 0 if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)): leap = 1 if (leap == 1) and (month > 2): sum += 1 print('这一天是这一年的第%d天'%sum)
有时,我们需要在多组动作中选择一组执行,这时就会用到多选结构,对Python语言来说,多选结构就是if…elif…else语句。该语句的语法形式如下所示:
if 表达式1 : 语句1 elif 表达式2 : 语句2 …… elif 表达式n : 语句n else : 语句n+1
注意,最后一个elif子句之后的else子句没有进行条件判断,它用于处理与前面所述条件都不匹配的情况,所以else子句必须放在最后。if…elif…else语句的流程图如图1-9所示。
图1-9 if…elif…else语句的流程图
【例1-2】输入学生的成绩score,按分数输出其等级:score≥90为优,90>score≥80为良,80>score≥70为中等,70>score≥60为及格,score<60为不及格。
score=int(input("请输入成绩")) #int()转换字符串为整型 if score >= 90: print("优") elif score >= 80: print("良") elif score >= 70: print("中等") elif score >= 60: print("及格") else : print("不及格")
说明:在三种选择语句中,条件表达式都是必不可少的组成部分。那么,哪些表达式可以作为条件表达式呢?一般地,最常用的是关系表达式和逻辑表达式,如:
if a == x and b == y : print ("a = x, b = y")
除此之外,条件表达式可以是任何数值类型表达式,当条件表达式的值为零时,表示条件为假;当条件表达式的值为非零时,表示条件为真。甚至字符串也可以:
if 'a': #'abc':也可以,被认为是True print ("a = x, b = y")
另外,C语言是用花括号{}来区分语句体,但是Python的语句体是用缩进形式来表示的,如果缩进不正确,则会导致逻辑错误。
2. 循环结构
程序在一般情况下是按顺序执行的。编程语言提供了各种控制结构,允许更复杂的执行路径。循环语句允许我们执行一个语句或语句组多次,Python提供了for循环和while循环(在Python中没有do…while循环)。
(1)while语句
Python中的while语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为:
while 判断条件: 执行语句
执行语句可以是单个语句或语句块。判断条件可以是任何表达式,任何非零或非空的值均为True;当判断条件为False时,循环结束。Which语句的流程图如图1-10所示。
图1-10 while语句的流程图
同样地,需要注意冒号和缩进。例如:
count = 0 while count < 5: print ('The count is:', count) count = count + 1 print ("Good bye!" )
(2)for语句
for语句可以遍历任何序列的项目,如一个列表、元组或者一个字符串。for循环的语法格式如下:
for 循环索引值 in 序列 循环体
for循环把列表中的元素遍历出来。例如:
fruits = ['banana', 'apple', 'mango'] for fruit in fruits: #第二个实例 print ( '元素 :', fruit) print( "Good bye!" )
运行上述代码后会依次打印fruits中的每一个元素,程序运行结果:
元素:banana 元素:apple 元素:mango Good bye!
【例1-3】计算1~10的整数之和,可以用一个sum变量进行累加。
程序代码:
sum = 0 for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]: sum = sum + x print(sum)
如果要计算1~100的整数之和,从1写到100十分烦琐。Python提供了一个range()内置函数,可以生成一个整数序列,再通过list()函数可以转换为list列表。
例如,range(0, 5)或range(5)生成的序列是从0开始小于5的整数,但不包括5。结果如下:
>>> list(range(5)) [0, 1, 2, 3, 4]
range(1, 101)就可以生成1~100的整数序列,计算1~100的整数之和如下:
sum = 0 for x in range(1,101): sum = sum + x print(sum)
(3)continue和break语句
break语句在while循环和for循环中都可以使用,一般放置于if选择结构中,一旦break语句被执行,将使整个循环提前结束。
continue语句的作用是终止当前循环,并忽略continue之后的语句,然后回到循环的顶端,提前进入下一次循环。
注意:除非break语句让代码更简单或更清晰,否则不要轻易使用。
【例1-4】continue和break用法示例。
#continue 和 break 用法 i = 1 while i < 10: i += 1 if i%2 > 0: #非双数时跳过输出 continue print (i) #输出双数2、4、6、8、10 i = 1 while 1: #循环条件为1必定成立 print (i) #输出1~10 i += 1 if i > 10: #当i大于10时跳出循环 break
在Python程序开发过程中,开发者将完成某一特定功能并经常使用的代码编写成函数,放在函数库(模块)中供大家选用,在需要使用时可直接调用。编程人员要善于使用函数,提高编码效率。
1.2.4 Python函数与模块
当执行某些任务时,如求一个数的阶乘,需要在一个程序中不同位置重复执行时,这样造成代码的重复率高,应用程序代码烦琐。解决这个问题的方法就是使用函数。无论在哪种编程语言当中,函数(在类中称作方法,意义是相同的)都扮演着至关重要的角色。模块是Python的代码组织单元,它将函数、类和数据封装起来以便重用,模块往往对应Python程序文件、Python标准库和第三方提供的大量的模块。
1. 函数定义
在Python中,函数定义的基本形式如下:
def 函数名(函数参数): 函数体 return 表达式或者值
在这里需要注意以下几点:
(1)在Python中采用def关键字进行函数的定义,不用指定返回值的类型;
(2)函数参数可以是零个、一个或者多个,同样地,函数参数也不用指定参数类型,因为在Python中变量都是弱类型的,Python会自动根据值来维护其类型;
(3)Python函数的定义中缩进部分是函数体;
(4)函数的返回值是通过函数中的return语句获得的。return语句是可选的,它可以在函数体内任何地方出现,表示函数调用执行到此结束。如果没有return语句,则会自动返回None(空值);如果有return语句,但是return后面没有接表达式或者值,也会返回None(空值)。
下面定义三个函数:
def printHello(): #打印'hello'字符串 print ('hello') def printNum(): #输出数值0~9 for i in range(0,10): print (i) return def add(a,b): #实现两个数的和 return a+b
2. 函数的使用
在定义了函数之后,我们就可以使用该函数了。但是在Python中要注意一个问题,就是在Python中不允许前向引用,即在函数定义之前,不允许调用该函数。实例如下:
print (add(1,2)) def add(a,b): return a+b
这段程序运行的错误提示如下:
Traceback (most recent call last): File "C:/Users/xmj/4-1.py", line 1, in <module> print (add(1,2)) NameError: name 'add' is not defined
从报错信息可以知道,名字为“add”的函数未进行定义。所以在任何时候调用某个函数,必须确保其定义在调用之前。
【例1-5】编写函数,计算形式如a + aa + aaa + aaaa +…+ aaa…aaa的表达式的值,其中,a为小于10的自然数。例如,2+22+222+2222+22222(此时n=5),a、n由用户从键盘输入。
分析:关键是计算出求和中每一项的值。容易看出每一项都是前一项扩大10倍后加a。
程序代码:
def sum (a, n): result, t = 0, 0 #同时将result、t赋值为0,这种形式比较简洁 for i in range(n): t = t*10 + a result += t return result #用户输入两个数字 a = int(input("输入a: ")) n = int(input("输入n: ")) print(sum(a, n))
程序运行结果:
输入a: 2↙ 输入n: 5↙ 24690
3. 闭包(closure)
在Python中,闭包指函数的嵌套。可以在函数内部定义一个嵌套函数,将嵌套函数视为一个对象,所以可以将嵌套函数作为定义它的函数的返回结果。
【例1-6】使用闭包的例子。
def func_lib(): def add(x, y): return x+y return add #返回函数对象 fadd = func_lib() print(fadd(1, 2))
在函数func_lib()中定义了一个嵌套函数add(x, y),并作为函数func_lib()的返回值。运行结果为3。
4. 函数的递归调用
函数在执行的过程中直接或间接调用自己本身,称为递归调用。Python语言允许递归调用。
【例1-7】求1~5的平方和。
def f(x): if x==1: #递归调用结束的条件 return 1 else: return(f(x-1)+x*x) #调用f()函数本身 print(f(5))
5. 模块
模块(module)能够有逻辑地组织Python代码段,可将相关的代码分配到一个模块里,让代码更简明实用。简单地说,模块就是一个保存了Python代码的文件。模块能定义函数、类和变量。
在Python中,模块与C语言中的头文件以及Java中的包很类似,如在Python中要调用sqrt函数,必须用import关键字引入math这个模块。
(1)导入某个模块
在Python中用关键字import来导入某个模块。方式如下:
import 模块名 #导入模块
比如,要引用模块math,就可以在文件最开始的地方用import math来导入。
在调用模块中的函数时,必须这样调用:
模块名.函数名
例如:
import math #导入math模块 print ("50的平方根:", math.sqrt(50))
为什么必须加上模块名这样调用呢?因为可能存在这样一种情况:在多个模块中含有相同名称的函数,此时如果只是通过函数名来调用,则解释器无法知道到底要调用哪个函数。因此,如果像上述这样导入模块时,调用函数必须加上模块名。
有时我们只需要用到模块中的某个函数,则只需要引入该函数即可,此时可使用from语句:
from 模块名 import 函数名1,函数名2…
通过这种方式引入时,调用函数时只能给出函数名,不能给出模块名,但是当两个模块中含有相同名称函数时,后面一次引入会覆盖前一次引入。
也就是说,假如模块A中有函数fun(),在模块B中也有函数fun(),如果引入A中的fun()在先、B中的fun()在后,那么,当调用fun()函数时,系统会去执行模块B中的fun()函数。
如果想一次性导入math中所有的内容,还可以通过如下代码实现:
from math import *
这是一种简单导入模块中的所有项目的方式,但最好不要过多地使用这种方式。
(2)定义自己的模块
在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。
比如,有这样一个文件fibo.py,在fibo.py中定义了三个函数add()、fib()和fib2():
#fibo.py #斐波那契(fibonacci)数列模块 def fib(n): #定义到 n 的斐波那契数列 a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a+b print() def fib2(n): #返回到 n 的斐波那契数列 result = [] a, b = 0, 1 while b < n: result.append(b) a, b = b, a+b return result def add(a,b): return a+b
那么,在其他文件(如test.py)中就可以按如下方式来使用:
#test.py import fibo
加上模块名称来调用函数:
fibo.fib(1000) #结果是1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 fibo.fib2(100) #结果是[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] test.add(2,3) #结果是5
当然也可以通过from fibo import add, fib, fib2来引入。
还可以直接使用函数名来调用函数:
fib(500) #结果是1 1 2 3 5 8 13 21 34 55 89 144 233 377
若列举fibo模块中定义的属性列表如下:
import fibo dir(fibo) #得到自定义模块fibo中定义的的变量和函数
输出结果:['__name__', 'fib', 'fib2', 'add']。