第五章 函数和代码复用
5.1 函数的定义和使用
5.2 实例7:七段数码管绘制
5.3 代码复用与函数递归
5.4 模块4:PyInstaller库的使用
5.5 实例8:科赫雪花小包裹
5.1 函数的定义和使用
(1)函数的理解
特点:函数是一段代码的表示;函数是一段具有特定功能的、可重用的语句组;函数是一种功能的抽象,一般函数表达特定功能;
作用:降低编程难度和代码复用;
(2)函数的定义
#函数的定义
def <函数名>(<参数(0个或多个)>):
<函数体>
return <返回值>
#范例,计算n!
def fact(n):
s = 1
for i in range(1,n+1):
s = s*i
return s
注意说明:函数定义时,所指定的参数是一种占位符;函数定义后,如果不经过调用,不会被执行;函数定义时,参数是输入,函数体是处理,结果是输出(IPO);
5.2 函数的使用与调用过程
(1)函数的调用
特点:调用时运行函数代码的方式;调用时要给出实际参数;实际参数替换定义中的参数;函数调用后得到返回值;
举例说明:如上述fact(n)的定义部分即为其函数定义,fact(10)为函数的调用;
(2)函数的参数传递
特点1:函数可以有参数,也可以没有,但必须保留括号;
#函数没有参数示例
def fact():
print("我也是函数”)
#调用时输入fact()
特点2:函数定义时可以为某些参数指定默认值,构成可选参数
def fact(n,m):
s = 1
for i in range(1,n+1):
s = s*i
return s//m
#其中,m为可选参数,默认值为1,调用方法fact(10,5)
特点3:函数定义时可以设计可变数量参数,即不确定参数总数量;
def fact(n,*b):
s = 1
for i in range(1,n+1):
s = s*i
for item in b:
s = s*item
return s
#其中*b可用于可变参数的定义,如代表(3,4,5),调用时fact(10,3,4,5)
#即可计算10!*3*4*5
特点4:函数调用时,参数可以按照位置或名称方式传递;
#位置传递
fact(10,5)#其中10代表非可选参数,5代表可选参数
#名称传递
fact(m=5,n=10)
特点5:函数可以返回0个或者多个结果;
return保留字用来传递返回值;函数可以有返回值,也可以没有,可以有return,也可以没有;return可以传递0个返回值,也可以传递任意多个返回值;
特点6:函数调用时,参数可以按照位置或者名称方式传递
#位置方式
def fact(n,m):
s = 1
for i in range(1,n+1):
s = s*i
return s//m,n,m
print(fact(10,5))
#输出为:(725760,10,5)该类型为元组类型
#也可利用a,b,c = fact(10,5)将元组中的值赋给所需变量
(3)局部变量和全局变量
规则1:局部变量和全局变量是不同的变量;
局部变量是函数内部占位符,与全局变量可能重名但是二者并不相同;
函数运算结束后,局部变量被释放;
可以使用global保留字在函数内部使用全局变量;
#局部变量与全局变量举例说明1
n,s = 10,100 #n,s为全局变量
def fact(n): #fact()函数中的n和s是局部变量
s = 1
for i in range(1,n+1):
s = s*i
return s #函数内部s执行完函数体后将值赋给fact(10)后即释放
print(fact(n),s) #n和是是全局变量,运行结果为3628800 100
#局部变量和全局变量举例2
n,s = 10,100
def fact(n):
global s #fact()函数中使用global保留字声明,此处s是全局变量s
for i in range(1,n+1):
s = s*i
return s #由于上面的声明,此处的s指全局变量s
print(fact(n),s) #因此此处的全局变量s被函数修改(可以理解为,程序自上向下执行的过程中,s已被替换) 输出结果362880000 362880000
规则2:局部变量为组合数据类型且未创建,等同于全局变量;
对比说明如下:
比较结果:由于在前者中,列表ls并未在函数内部被创建,因此可以等同于全局变量;而在后者中,列表ls在函数内部被真实创建,因此视为局部变量;
(4)lambda函数
特点:lambda函数是一种匿名函数,即没有名字的函数;使用lambda保留字定义,函数名是返回结果;lambda函数用于定义简单的、能够在一行内表示的函数;
#lambda函数定义举例
f = lambda x,y : x+y
#调用f(10,15),输出25
注意,一般建议使用def定义普通函数
5.3 代码复用与函数递归
(1)代码复用与模块化设计
代码复用:同一份代码在需要的时可以被重复使用;
代码复用的主要形式:函数和代码;
模块化设计:通过函数或对象封装将程序划分为模块及模块间的表达;
包括:主程序,子程序,子程序间关系;
思想:模内部紧耦合,模块间松耦合;
紧耦合:两个部分之间交流很多,无法独立存在;
松耦合:两个部分之间交流很少,可以独立存在;
(2)函数递归的理解
递归:函数定义中调用函数自身的方式;
递归的特征:计算过程存在递归链条;存在一个或多个不需要再次递归的基例;
总结:类似于数学归纳法,先找出初始化的点(不需要递归,可直接计算),再计算递归链条;
# 递归的简单举例1
def fact(n):
if n == 0: #此处为基链
return 1 #return值返回给fact(n)
else:
return n*fact(n-1) #递归链条,由果溯因?
print(fact(10))
#hanoi.py
count = 0
def hanoi(n,src,dst,mid):
global count
if n ==1:
print("{}:{}-->{}".format(1,src,dst))
count = count + 1
else:
hanoi(n-1,src,mid,dst)
print("{}:{}-->{}".format(n,src,dst))
count = count + 1
hanoi(n-1,mid,dst,src)#相当于src与mid交换位置
hanoi(3,"a","c","b")
print(count)
5.4 模块4:PyInstaller库的使用
作用:将.py源代码转换成无需源代码的可执行文件;
#可在cmd命令行中,执行pip install pyinstaller安装pyinstaller库
pyinstaller -F <文件名.py> #进行封装打包
pyinstaller-i curve.ico-F DAYDAYUP.PY #添加图标,图标文件为.ico格式