来源引用网络知识与某站曹老师视频相互结合学习记录,仅供参考!
Python 基础知识
三、函数
函数是执行特定任务的一段代码,程序通过将一段代码定义成函数,并为该函数指定一个函数名,这样即可在需要的时候多次调用这段代码;例如:之前使用的 range() 函数,就是系统内置的函数,功能是通过传入参数,返回特定范围的数字序列,函数名是 range,当需要使用的时候,可以直接调用函数名,可反复多次使用;
函数的定义
函数的定义语法:
def 函数名(形参列表):
函数体(由零条或多条可执行语句组成的函数)
return 返回值
-
函数名要符合标识符定义,取名的时候要有意义,看名知义;
-
形参列表是定义该函数可以接受的参数,可以为空,多个参数之间使用逗号隔开,调用函数的地方传入对应的参数值;
-
return 返回值,返回函数的执行结果,若没有返回值可省略;
定义一个最基础的函数,例如 say_helloworld
def say_helloworld():
print("Hello World!")调用函数,直接使用函数名 say_helloworld
say_helloworld()
再次调用 say_helloworld 函数
say_helloworld()
运行结果
Hello World!
Hello World!
函数的参数
函数形参部分,可以不定义参数,直接空括号即可;若有多个参数,可以使用 "," 逗号隔开;在调用的时候,传入的就是实际参数,按照形参定义,顺序传入即可;
# 定义一个加法函数
def add(a, b):
result = a + b
print(f'{a} + {b} = {result}')
# 调用函数
add(1, 2)
add(3, 4)
add(5, 6)
运行结果
1 + 2 = 3
3 + 4 = 7
5 + 6 = 11
关键字(keyword)参数
上面的实例中是位置参数,在调用的时候,必须严格按照定义函数时指定的顺序来传入参数值;若根据参数名来传入参数值,则无需蹲守定义形参的顺序,这种方式被称为关键字(keyword)参数;
注意点:
-
在使用关键字参数的时候,顺序可以随便换;
-
部分使用关键字参数,部分使用位置参数;
-
混合使用的时候,关键字参数必须位于位置参数之后,否则会报错;
定义一个加法函数
def add(a, b):
result = a + b
print(f'{a} + {b} = {result}')根据关键字参数来传入数值
add(a=1, b=2)
在使用关键字参数的时候,指定参数名后,顺序可以随意更换
add(b=2, a=3)
混合使用,部分使用位置参数,部分使用关键字参数
add(4, b=5)
在混用时,关键字参数务必要在位置参数之后,否则报错
add(b=6, 7)

参数默认值
在某些情况下,程序需要在定义函数时为一个或多个形参指定默认值;这样在调用函数时就可以省略为该形参传入参数值,而是直接使用该形参的默认值;
语法格式:形参名=默认值
# 定义一个加法函数
def say(name='张三', msg='法外狂徒'):
print(f'{name} 的称号是:{msg}')
# 全部使用默认参数
say()
# 部分使用默认参数
say('李四')
# 都不使用默认参数
say('王二', '客栈王小二弟弟')
# name使用默认参数值,msg则需要使用关键字参数
say(msg='西行记大师')
运行结果
张三 的称号是:法外狂徒
李四 的称号是:法外狂徒
王二 的称号是:客栈王小二弟弟
张三 的称号是:西行记大师
注意点:
- 可以全部使用默认参数;
- 可以部分使用默认参数;
- 可以全部不使用默认参数;
- 假如前面参数使用默认参数,后面的参数需要使用关键字参数;
- Python 要求将带有默认值的参数定义,放在形参列表的最后;
函数的返回值
函数执行完毕,可以返回数据给方法的调用者;可以通过 return 关键字返回多个数据;
# 定义一个加法函数
def add(a, b):
result = a + b
# 通过return关键字,把a+b的结果返回给函数的调用者
return result
# 定义变量r,接收函数的返回值
r = add(1, 2)
print(f'调用add(1,2)的返回值结果是:{r}')
# 定义变量r2,接收函数的返回值
r2 = add(3, 4)
print(f'调用add(3,4)的返回值结果是:{r2}')
运行结果
调用add(1,2)的返回值结果是:3
调用add(3,4)的返回值结果是:7
如果程序需要多个返回值,则即可将多个值包装成列表之后返回,也可直接返回多个值;如果 Python 函数直接返回多个值,Python 会自动将多个返回值封装成元组;如果函数没有使用 return 语句返回数据,则函数返回的是 None 值(None 是空的意思);
# 定义一个最基础的函数,例如 say_helloworld
def say_helloworld():
print("Hello World!")
# 调用函数
result = say_helloworld()
print(f'返回的结果是:{result},返回的类型是:{type(result)}')
运行结果
Hello World!
返回的结果是:None,返回的类型是:<class 'NoneType'>
这个 None 值有哪些作用呢?
1、可以用于 if 判断;
2、可以用于声明无初始化内容的变量;
# 定义一个最基础的函数,例如 say_helloworld
def check_user(username, password):
if username == 'test01' and password == '123456':
return 'success'
else:
return None
result = check_user('test01', '123456789')
print(f'返回的结果是:{result}')
# 1,可以用于if判断
# if result == None:
# 可以省略,直接使用not
if not result:
print('登录失败!')
# 2,可以用于声明无初始化内容的变量
usernames = None
print(usernames)
运行结果
返回的结果是:None
登录失败!
None
函数的说明文档
使用""" """ (三个引号)备注说明,然后在调用函数的地方,鼠标移动上去就能看到函数的说明,提供代码的可读性;
def add(a, b):
"""
两数相加函数
:param a: 两数相加数中的a
:param b: 两数相加数中的a
:return: 两数相加的结果
"""
return a + b
add(1, 2)

变量作用域
在程序中定义一个变量时,这个变量是有作用范围的,变量的作用范围被称为它的作用域;
根据定义变量的位置,变量分为两种:
局部变量:在函数中定义的变量,包括参数,都被称为局部变量;
全局变量:在函数外面、全局范围内定义的变量,被称为全局变量;
1、局部变量
def test():
name = 'abc123'
# 在方法里面定义局部变量name
print(name)
test()
# 局部变量,外面无法使用
print(name)

2、全局变量
name2 = 'test01'
def name_test():
name = 'abc123'
# 在方法里面定义局部变量name
print(name)
name_test()
# 局部变量,外面无法使用
# print(name)
# 打印全局变量
print(name2)
运行结果
abc123
test01
使用 global 关键字声明全局变量;
name_t = 'test01'
def name_test():
name_a = 'abc123'
# 在方法里面定义局部变量name
print(name_a)
global name_d
name_d = 'dev007'
name_test()
# 局部变量,外面无法使用
# print(name_a)
# 打印全局变量
print(name_d)
运行结果
abc123
dev007
递归函数
在一个函数体内调用它自身,被称为函数递归(自己调用自己);函数递归包含了一种隐式的循环,它会重复执行某段代码,但是这种重复执行无需循环控制;
例如:求 1+2+3+...+100 之和,使用递归实现;数学公式:f(n)=n+f(n-1)
def cel(n):
# 递归出口
if n == 1:
return 1
return n + cel(n-1)
print(cel(100))
运行结果
5050
注意点:递归算法,必须要有一个递归出口条件,否则会无限死循环;
斐波那契数列
示例:斐波那契数列递归解法
0、1、1、2、3、4、5、13、21、34、55、89、...... 这个数列从第3项开始,每一项都等于前两项之和;显然这是一个线性递推数列。
在数学上,斐波那契数列以如下被以递推的方法定义:
F(0)=0,
F(1)=1,
F(n)=F(n-1)+F(n-2) (n>=3,n∈N*)
def cel(n):
# 递归出口,基本情况:F(0)=0,F(1)=1
if n == 0:
return 0
elif n == 1:
return 1
# 递归情况:F(n)=F(n-1)+F(n-2)
else:
return cel(n - 1) + cel(n - 2)
# 计算斐波那契数列的第m个数字
m = 15
print(f'斐波那契数列的第{m}个数字是:{cel(m)}')
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为"兔子数列",指的是这样一个数列:1、1、2、3、5、8、13、21、34、......在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=1,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
拓展:
斐波那契数,亦称之为斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列、费波那西数列、费波拿契数、费氏数列和兔子数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、......在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*),用文字来说,就是斐波那契数列列由 0 和 1 开始,之后的斐波那契数列系数就由之前的两数相加。
由来:
在数学历史上,欧洲黑暗时期过后,第一位有影响的数学家是斐波那契(L.Fibonacci,1170一1250)。他早年就随其父在北非师从阿拉伯人学习算学,后又游历地中海沿岸诸国,回意大利后写成《算经xq2 》,也翻译成《算盘书》。这部很有名的著作主要是一些源自古代中国、印度和希腊的数学问题的汇集,内容涉及整数和分数算法、开方法、二次和三次方程以及不定方程。特别是,在1228年的《算经》修订版上载有如下"兔子问题":
如果每对兔子(一雄一雌)每月能生殖一对小兔子(也是一雄 一xq3 雌,下同),每对兔子第一个月没有生殖能力,但从第二个 月xq4 以后便能每月生一对小兔子.假定xq5 这些兔子都没有死亡现象,那么从第一对刚出生的兔子开始,12 个月以后会有多少 对xq6 兔子呢? 解释说明为:一个月xq7 :只有一对兔子;第二个月: 仍然只有一对兔子;第三个月:这对兔子生了一对小兔子, 共有 1+1=2 对兔子.第四个月xq8 :最初的一对兔子又生一对兔 子,共有 2+1=3 对兔子.则由第一个月到第十二个月兔子的 对数分别是:1,1,2,3,5,8,13,21,34,55,89,144, ......,后 人xq9 为了纪念提出兔子繁殖问题的斐波纳契, 将这个兔子数 列xq10 称为斐波那契数列, 即把 1,1,2,3,5,8,13,21,34......这样的数列称为斐波那契数列。
未完待续......