Python基础语法(4)
函数的定义与使用
函数的理解与定义
- 概念:函数是一段代码的表示;是一段具有特定功能的、可重用的语句组;是一种功能的抽象,一般函数表达特定功能。作用是降低编程难度和代码复用。
- 函数的定义:
def <函数名>(参数(0个或多个)):
<函数体>
return <返回值>
定义时,所指定的参数是一种占位符,定义后如果函数经过调用就不会被执行;参数是输入,函数体是处理,返回值是输出(IPO)。
def fact(n) :
s = 1
for i in range(1, n+1) :
s *= i
return s
函数的使用及调用过程
调用时要给出实际参数,实际参数替换定义中的参数,调用后得到返回值
def fact(n) :
s = 1
for i in range(1, n+1) :
s *= i
return s
fact(10)
函数的参数传递
- 参数的个数
函数可以有参数,也可以没有参数,但是括号必须保留
def fact() :
print('我也是函数')
- 可变参数传递
函数定义时可设计可变数量参数,即不确定参数总数量
def <函数名>(<参数, *b>) : # *a, *c都可以
<函数体>
return <返回值>
def fact(n, *b) :
s = 1
for i in range(1, n+1) :
s *= i
for item in b :
s *= item
return s
>>> fact(10, 3)
10886400
>>> fact(10, 3, 5, 8)
435456000
- 可选参数传递
函数定义时可以为某些参数指定默认值,构成可选参数
def <函数名>(<非可选参数, 可选参数>) :
<函数体>
return <返回值>
def fact(n, m=1) :
s = 1
for i in range(1, n+1) :
s *= i
return s // m
- 参数传递的两种方式
def fact(n, m=1) :
s = 1
for i in range(1, n+1) :
s *= i
return s // m
>>> fact(10, 5) # 位置传递
725760
>>> fact(m=5, n=10) # 名称传递
725760
函数的返回值
函数可以返回0个或多个结果;使用return来传递返回值;函数可以有返回值,也可以没有,可以有return,也可以没有;return可以传递0个返回值,也可以传递任意多个返回值。
def fact(n, m=1) :
s = 1
for i in range(1, n+1) :
s *= i
return s//m, n, m
>>> fact(10, 5)
(725760, 10, 5) # 元组类型
>>> a, b, c = fact(10, 5)
>>> print(a, b, c)
725760, 10, 5
局部变量和全局变量
全局变量和局部变量的区别在于作用域,全局变量在整个py文件中声明,全局范围内可以使用;局部变量是在某个函数内部声明的,只能在函数内部使用,如果超出使用范围(函数外部),则会报错。
n, s = 10, 100 # n和s是全局变量
def fact(n) :
s = 1
for i in range(1, n+1) : # fact()中的n和s是局部变量
s *= i
return s
print(fact(n), s) # n和s是全局变量
>>> 3628800, 100
- 规则1:局部变量和全局变量是不同变量
- 局部变量是函数内部的占位符,与全局变量可能重名,但不同
- 函数运算结束后,局部变量被释放
- 可以使用global保留字在函数内部调用全局变量
n, s = 10, 100
def fact(n) :
global s # fact()函数中使用global保留字声明此处的s是全局变量s
for i in range(1, n+1) :
s *= i
return s # 此处s指全局变量s
print(fact(n), s) # 此处全局变量s被修改
>>> 362880000, 362880000
- 规则2:局部变量是组合数据类型且未创建,等同于全局变量
ls = ['f', 'F'] # 通过使用[]创建一个全局变量列表ls
def func(a) :
ls.append(a) # 此处ls是列表类型,未真实创建则等同于全局变量
return
func('C') # 全局变量ls被修改
print(ls)
>>> ['f', 'F', 'C']
ls = ['F', 'f'] # 通过使用[]创建一个全局变量列表ls
def func(a) :
ls = [] # 此处ls是列表类型,真实创建,ls是局部变量
ls.append(a)
return
func('C') # 局部变量被修改
print(ls) # 输出全局变量
>>> ['F', 'f']
lambda函数
- lambda函数返回函数名作为结果
- lambda函数是一种匿名函数,即一种没有名称的函数
- 使用lambda保留字定义,函数名是返回结果
- lambda函数用于定义简单、能够在一行内表示的函数
<函数名> = lambda <参数>: <表达式>
等价于
def <函数名>(<参数>) :
<函数体>
return <返回值>
>>> f = lambda x, y: x + y
>>> f(10, 15)
25
>>> f = lambda : 'lambda函数'
>>> print(f())
lambda函数
注
:谨慎使用lambda函数
- lambda函数主要作用一些特定函数或方法的参数
- lambda有一些固定使用方式
- 一般情况下,建议使用def定义的普通函数
代码复用和函数递归
代码复用
把代码当作资源进行抽象
代码资源化:程序代码是一种用来表达计算的“资源”
代码抽象化:使用函数等方法对代码赋予更高级别的定义
代码复用:同一份代码在需要时可以重复
函数和对象是代码复用的两种主要形式
函数:将代码命名,在代码层面建立了初步的抽象
对象:属性和方法,<a>.<b>或者<a>.<b>(),在函数层面再次组织进行抽象
模块化设计
- 分而治之
- 通过函数或对象封装将程序划分为模块和模块间的表达
- 具体包括:主程序、子程序和子程序间的关系
- 分而治之:一种分而治之、分层抽象、体系化的设计思想
- 紧耦合和松耦合
紧耦合:两个部分交流很多,无法独立存在
松耦合:两个部分交流很少,可以独立存在
模块内部之间紧耦合,模块之间松耦合
函数递归
- 定义:函数定义中调用函数自身的方式
- 两个关键特征:
- 基例:存在一个或多个不需要再次递归的基例
- 链条:计算过程中存在递归链条
- 调用过程
示例:(求n的阶乘)
def fact(n):
if n == 0:
return 1
else :
return n * fact(n-1)
- 递归的实现
函数+分支语句
- 递归本身是一个函数,需要函数定义方式描述
- 函数内部采用分支语句对输入参数进行判断
- 基例和链条分别编写对应代码
实例(汉诺塔问题):
steps = 0
def hanoi(src, des, mid, n):
global steps
if n == 1:
steps += 1
print("[STEP{:>4}] {}->{}".format(steps, src, des))
else:
hanoi(src, mid, des, n-1)
steps += 1
print("[STEP{:>4}] {}->{}".format(steps, src, des))
hanoi(mid, des, src, n-1)
N = eval(input())
hanoi("A", "C", "B", N)