做二手房网站,做网站需要什么技术支持,系部网站开发项目的目的,wordpress腾讯云cos前言
上篇文章 python学习——【第七弹】学习了python中的可变序列集合#xff0c;自此python中的序列的学习就完成啦#xff0c;这篇文章开始学习python中的函数。 函数
在学习其他编程语言的时候我们就了解过函数#xff1a;函数就是执行特定任何以完成特定功能的一段代…前言
上篇文章 python学习——【第七弹】学习了python中的可变序列集合自此python中的序列的学习就完成啦这篇文章开始学习python中的函数。 函数
在学习其他编程语言的时候我们就了解过函数函数就是执行特定任何以完成特定功能的一段代码
那么我们为什么要使用函数呢 复用代码 隐藏实现细节 提高可维护性 提高可读性便于调试 函数的创建
python中函数的创建方式 def 函数名 ([输入参数]): 函数体 [return xxx] 形参:形参出现在函数的定义处 实参:实际参数的值,位置出现在函数的调用处 函数的调用
在学习其他的语言时我们知道函数只有在调用的时候才能执行python中的函数也是一样的。调用函数的方式也很简单
[返回值] 函数名([参数])
如果函数没有参数则括号中可以留空def pri():print(helloworld)
pri()#调用函数 那么在调用函数时对调用的参数有什么要求呢
函数调用的参数传递 位置实参根据形参对应的位置进行实参传递 def add(a,b):numabreturn num
resultadd(10,20)
print(result) #30关键字实参根据形参名称进行实参传递 def add(a,b):numabreturn num
resultadd(b10,a20)
print(result) #30需要注意的是创建函数有多少个形参那么调用时就需要传入多少个值且顺序必须和创建函数时一致。即便该函数没有参数函数名后的小括号也不能省略。 函数参数的定义
函数定义时给形参设置默认值只有与默认值不符的时候才需要传递实参
def fun1(a,b10):print(a,b)
# 函数调用
fun1(100) #100 10
fun1(20,30) #20 30 与默认形参值不相符传递实参值个数可变的位置形参 1定义函数时,可能无法事先确定传递的位置的实参的个数,可以使用可变的位置参数 2使用 * 定义个数可变的位置形参 3结果为元组类型 4如果没有需传递的位置实参,但是使用了可变的位置参数,这时再调用该函数,会返回一个空元组 即args() def fun1(*args):print(args,type(args))
fun1(10)
fun1(10,20)
fun1(10,20,30)(10,) class tuple
(10, 20) class tuple
(10, 20, 30) class tupledef fun11(x,y,*args): #已知形参(x,y)要放在位置形参之前;否则会报 SyntaxError: invalid syntax 无效语法错误print(x,x)print(y,y)print(args,args)
fun11(11,22,33,44,55)
x 11
y 22
args (33, 44, 55)注意使用个数可变的位置参数时,可变的位置参数只能是1个
个数可变的关键字形参 1定义函数时,无法事先确定确定传递的关键字实参的个数时,使用可变的关键字形参 2使用 ** 定义个数可变的关键字形参 3结果是一个字典 4如果没有需要传递的关键字实参,但是使用了可变的关键字参数,这时再调用该函数,会返回一个空字典 即args{} def fun2(**args):print(args,type(args))
fun2(a10)
fun2(a10,b20,c30){a: 10} class dict
{a: 10, b: 20, c: 30} class dict
def fun22(x,y,**args): #已知形参(x,y)要放在关键字形参之前;并且位置实参的个数要和位置形参的个数保持一致否则会报TypeError: fun22() takes ... positional arguments but ... were given 实参数与形参数不符print(x,x)print(y,y)print(args,args)
fun22(11,22,c10,d0){a: 10}
{a: 10, b: 20, c: 30}注意使用个数可变的关键字形参时,可变的关键字形参只能是1个
def fun6(**args,**args):pass
# 程序报错 SyntaxError: invalid syntax 无效语法定义函数的过程中既有个数可变的关键字形参也有个数可变的位置形参要求个数可变的位置形参放在个数可变的关键字形参之前。
def fun(x, y, *args, **argss):print(x, x)print(y, y)print(args, args)print(argss, argss)
fun(1, 2, 3, 4, e5, f6, g7) x 1
y 2
args (3, 4)
argss {e: 5, f: 6, g: 7}# 可变位置参数和可变关键字参数需要传递的实参数不相匹配时如果可变位置参数或可变关键字参数没有收到需要传递的实参的值的话调用函数时分别返回空元组和空字典。
def fun(x, y, *args, **argss):print(x, x)print(y, y)print(args, args)print(argss, argss)
fun(3, 4) x 3
y 4
args ()
argss {}函数参数的传递
位置参数的传递
def funs(a,b,c):print(a,a)print(b,b)print(c,c)
funs(10,20,30)
lst[11,22,33]
funs(*lst)# 使用位置参数传递在函数调用时将列表中的每个元素都转换为位置参数传入a 10
b 20
c 30
a 11
b 22
c 33关键字参数的传递
# 关键字参数传递
funs(a111,b222,c333)
dic{a:444,b:555,c:666}
funs(**dic)# 使用关键字参数传递在函数调用时将字典中的每个元素的键值对都转换为关键字参数传入a 111
b 222
c 333
a 444
b 555
c 666在 * 之后的参数在函数调用时只能采用关键字参数进行传递
def funcs(a,b,*,c,d):print(a,a)print(b,b)print(c,c)print(d,d)
funcs(10,20,c30,d40)a 10
b 20
c 30
d 40函数传递时形参的位置问题 函数的参数总结 1 将序列中的每个元素都转换为位置实参 使用* 2 将字典中的每个键值对都转换为关键字实参 使用 ** 3 关键字形参 使用* 4 个数可变的位置形参 使用* 5 个数可变的关键字形参 使用** 函数调用参数传递内存分析
def fun(num1,num2):print(num1,num1,id(num1)) #num1 90 140471326216032print(num2,num2,id(num2)) #num2 [11, 22, 33, 44] 140471317443120num1111num2.append(999)print(num1,num1,id(num1)) #num1 111 140471326216704print(num2,num2,id(num2)) #num2 [11, 22, 33, 44, 999] 140471317443120
print(---------调用函数之前---------)
add190
add2[11,22,33,44]
print(add1,id(add1)) #90 140471326216032
print(add2,id(add2)) #[11, 22, 33, 44] 140471317443120
print(-------------调用函数----------)
fun(add1,add2)num1 90 140471326216032
num2 [11, 22, 33, 44] 140471317443120
num1 111 140471326216704
num2 [11, 22, 33, 44, 999] 140471317443120print(-----------调用函数后----------)
print(add1,id(add1)) #90 140471326216032
print(add2,id(add2)) #[11, 22, 33, 44, 999] 140471317443120可以发现在函数调用过程中,若要进行参数传递 如果是可变对象如列表、集合、字典,在函数体内对其进行修改会影响到函数体外的这个可变对象的值因为可变对象在内存中是可变的可以被修改其id地址不会发生改变 如果是不可变对象如数值、字符串、元组,在函数体内对其进行修改不会影响到函数体外这个不可变对象的值因为不可变对象在内存中是固定的无法被修改其id地址不会发生改变。 函数返回值
1当函数不需要返回值时函数体内可以省略return并且函数执行完毕后,不需要给调用处提供数据
def pri():print(helloworld)
pri()2当函数只有一个返回值时返回值类型就是原类型
def fun2():return hello
resfun2()
print(res,type(res)) #hello class str3当函数有多个返回值时返回值类型是一个元组
def fun(num):odd[]even[]for i in num:if i%20:odd.append(i)else:even.append(i)return odd,even
list1[11,22,32,23,45,6,0]
print(fun(list1),type(fun(list1)))
# ([22, 32, 6, 0], [11, 23, 45]) class tuple变量的作用域
程序代码能访问该变量的区域 称作变量的作用域
根据变量的有效范围可分为
局部变量
在函数体内定义并使用的变量,只在函数内部有效局部变量使用global声明 这个变量就会成为全局变量
def func1(a,b):cab #c 就成为局部变量 因为c是在函数体内进行定义的变量 ab是函数的形参 作用范围也是函数内部 相当于局部变量return c
print(func1(1,2))#3# 使用global 声明局部变量,a b为全局变量在函数体内可以直接被调用c在函数体内定义属于局部变量因此需要用global声明才能在函数体外被调用
a1
b2
def func3():global cca-breturn c
print(func3()) #-1全局变量
函数体外定义的变量 可作用于函数体内
# 全局变量 a1,b2为定义在函数体外的变量属于全局变量在函数体内与函数体外均可调用
a1
b2
def func2():cabreturn c
print(func2()) #3递归函数
什么是递归函数 如果在一个函数的函数体内调用了该函数本身, 这个函数就称作递归函数
递归的组成部分 递归调用与递归终止条件
递归的调用过程 每递归调用一次函数 都会在栈内存分配一个栈帧每次调用函数时在内存中都会单独开辟一个空间配合函数运行这个空间叫做栈帧空间。每执行完一次函数 都会释放相应的空间
递归的思想 递归是一去一回的过程调用函数时会开辟栈帧空间函数执行结束之后会释放栈帧空间递归实际上就是不停地开辟和释放栈帧空间的过程每次开辟栈帧空间都是独立的一份其中的资源不共享。 递归其实利用的时是压栈的思想我们看一下下面这个例子 压栈思想
递归的优缺点
优点 递归函数使代码看起来干净整洁。
使用递归可以将复杂的任务分解为更简单的子问题。
与使用嵌套嵌套相比使用递归更容易生成序列。缺点 有些情况递归背后的逻辑很难遵循。
递归调用很昂贵效率低因为它们占用大量内存和时间。
递归函数调试较为复杂。递归函数的应用
利用递归函数计算阶乘
def func1(n):if n 1:return 1else:return n*func1(n-1)
print(func1(6)) #720利用递归函数计算 斐波那契数列 斐波那契数列1、1、2、3、5、8、13、21、34。。。 F(0)0F(1)1, F(n)F(n - 1)F(n - 2)n ≥ 2n ∈ N* 计算第n位的斐波那契数是多少
def func2(n):if n 1:return 1elif n 2:return 1else:resfunc2(n-1)func2(n-2)return res
print(func2(6)) #8打印出整个斐波那契数列
for i in range(1,7):print(func2(i),end )
print(\n)#1 1 2 3 5 8 键盘录入一个整数然后根据这个正整数打印出斐波那契数列以及其数列和
numint(input(请输入一个正整数))
def func3(num):if num1:return 1elif num2:return 1else:resultfunc3(num-1)func3(num-2)return result
nums[]
sums0
for n in range(1,num1):# print(func3(n),end )nums.append(func3(n))sumsfunc3(n)
print(产生的斐波那契数列是:,nums)
print(\n第,num,位的斐波那契数为,func3(num))
print(\n斐波那契数列之和为:,sums)每篇一语
努力的人运气都不会太差
如有不足感谢指正