05. 函数和代码复用

1. 函数的定义与使用

函数是一段具有特定功能的、可重用的语句组

  • 函数是一种功能的抽象,一般函数表达特定功能
  • 两个作用:降低编程难度 和 代码复用

可变参数传递
函数定义时可以设计可变数量参数,既不确定参数总数量

1
2
3
def <函数名>(<参数>, *b ) :
<函数体>
return <返回值>

参数传递的两种方式
函数调用时,参数可以按照位置或名称方式传递

函数调用时,参数可以按照位置或名称方式传递
当返回对个则是元组类型

1
2
3
4
5
6
def fact():
return 1, 2, 3, 4


i, j, k, m = fact()
print(i, j, k, m)

局部变量和全局变量

  • 基本数据类型,无论是否重名,局部变量与全局变量不同
  • 可以通过global保留字在函数内部声明全局变量
  • 组合数据类型,如果局部变量未真实创建,则是全局变量

因为 Python 是隐式定义变量, 没有指定初始数据类型, 在方法内定义就成了局部变量, 只有通过 global 区分了

lambda 函数

lambda函数返回函数名作为结果

1
2
3
4
5
6
<函数名> = lambda <参数>: <表达式>

# 等价于
def <函数名>(<参数>):
<函数体>
return <返回值>

谨慎使用lambda函数

  • lambda 函数主要用作一些特定函数或方法的参数
  • lambda 函数有一些固定使用方式,建议逐步掌握
  • 一般情况,建议使用def定义的普通函数

2. 实例: 七段数码管回执

3. 代码复用与函数递归

把代码当成资源进行抽象

  • 代码资源化:程序代码是一种用来表达计算的"资源"
  • 代码抽象化:使用函数等方法对代码赋予更高级别的定义
  • 代码复用:同一份代码在需要时可以被重复使用

代码复用
函数对象 是代码复用的两种主要形式
函数:将代码命名在代码层面建立了初步抽象
对象:属性和方法 <a>.<b><a>.<b>() 在函数之上再次组织进行抽象

模块化设计

分而治之
  • 通过函数或对象封装将程序划分为模块及模块间的表达
  • 具体包括:主程序、子程序和子程序间关系
  • 分而治之:一种分而治之、分层抽象、体系化的设计思想

模块化设计

紧耦合 松耦合
  • 紧耦合:两个部分之间交流很多,无法独立存在
  • 松耦合:两个部分之间交流较少,可以独立存在
  • 模块内部紧耦合、模块之间松耦合

递归的定义(基例 和 链条)

汉罗塔问题

1
2
3
4
5
6
7
8
9
10
11
12
def haoi(n, src, dst, mid):
if n == 1:
print("盘{}:{}->{}".format(1, src, dst))
else:
# 前 n-1 个盘通过 dst 盘移到 mid 盘
haoi(n-1, src, mid, dst)
# 首盘通过dst移动到mid盘
print("盘{}:{}->{}".format(n, src, dst))
# 前n-1个盘通过src盘移到det盘
haoi(n-1, mid, dst, src)

## haoi(5, 'A', 'C', 'B')

4. PyInstaller库的使用

将.py源代码转换成无需源代码的可执行文件

  1. 在安装pip前,请确认你win系统中已经安装好了python,和easy_install工具,如果系统安装成功,easy_install在目录C:\Python27\Scripts 下面
  2. 进入命令行,然后把目录切换到python的安装目录下的Script文件夹下,运行 easy_inatall pip
  3. pip install pyinstaller
  4. (cmd命令行) pyinstaller -F <文件名.py>
    PyInstaller库常用参数

5. 科赫雪花小包裹

用Python绘制科赫曲线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import turtle

def koch(size, n):
if n == 0:
turtle.forward(size)
else:
distance = size / 3
for angle in (0, 60, -120, 60):
turtle.left(angle)
koch(distance, n-1)


turtle.setup(600, 600)
turtle.penup()
turtle.goto(-200, 100)
turtle.pendown()
turtle.pensize(2)

# 阶数
level = 2
# 边长
distance = 400
# 几条边
severalSide = 3

avgAngle = 360 / severalSide
for i in range(severalSide):
koch(distance, level)
turtle.right(avgAngle)
turtle.hideturtle()
turtle.done()