Python学习9"/>
Python学习9
python学习9
函数(进阶)
1. 函数的概念
函数的命名,和变量名规则相同
def func():pass #pass是空语句,占位作用print("函数被调用了")# 函数调用
func()print(id(func),type(func)) #函数名本身也查看地址(Hash值),以及类型
函数名也可以作为变量进行赋值\传递\存储
def func1():print("func1...")def func2():print("func2...")def func3():print("func3...")res = func1 #函数名本身也是引用类型,保存的是函数体所在地址空间的内存地址(hash值)print(id(res),id(func1))res() #指向函数体的变量名,可以通过追加小括号,实现函数的调用myfuncs = [func1,func2,func3] #函数名可以作为元素,存储在列表中等容器类型中for f in myfuncs: #可以进行迭代f() #通过括号实现列表中函数逐一调用的效果
2. 参数
标准参数
(定义时)默认的形式参数,与调用时的位置,逐一对应赋值。
(调用时)标准参数:主要分为”位置参数“和”默认参数“两种方式。
位置参数:
def printInfo(a,b):print(a,b)#printInfo(10) #报错
printInfo(10,20,30) #使用位置参数时,参赛、形参数量要一致;否则报错
默认参数:
(定义时)形式参数指定默认值。
(调用时)可以和位置参数一样进行赋值,也可以不进行赋值;不赋新值,则为默认值。
def prinfInfo(name,age=18):print(f"姓名:{name},年龄:{age}")prinfInfo("张三",20)
prinfInfo("李四") #调用时,默认参数可以不赋值def printInfo(name="王五",age): #SyntaxError: non-default argument follows default argumentprint(f"姓名:{name},年龄:{age}")printInfo(20)
注意:”默认参数“只能在”位置参数“后,进行定义。
指定参数名赋值
指的是函数调用时, 根据参数名,进行针对性赋值
def prinfInfo(name="王五",age=18,gender="男"):print(f"姓名:{name},年龄:{age},性别:{gender}")# prinfInfo(name="张三",age=20)
prinfInfo(age=20,name="张三") # 因为制定了形参变量名,所以可以不按照位置循序传递参数prinfInfo("小红",gender="女",age=18)
#prinfInfo(gender="女",age=18,"小红") #如果 关键字实参 和 位置实参 混合使用,位置实参在前面。否则报错。
可变(个数的)参数
可变参数: *args :将多个参数存储为元组对象
关键字参数: **kwargs:将多个参数存储为字典对象
可变参数
函数定义时*args可以接受任意多个实际参数,args可以替换为任意变量名,符合变量名命名规则就可以
def prinfInfo(name,age,gender,*args):print(f"姓名:{name},年龄:{age},性别:{gender}")#print(args,type(args))print("作品评分自高到低为:",args)#他参与的电影评分
prinfInfo("张三",25,"男",9.5,8.0,8.6)
"""
姓名:张三,年龄:25,性别:男
作品评分自高到低为: (9.5, 8.0, 8.6)
"""
关键字参数
函数定义时, **kwargs可以接受任意多个键值对形式的实际参数。
def prinfInfo(name,age,gender,**kwargs):print(f"姓名:{name},年龄:{age},性别:{gender}")#print(args,type(args))print(kwargs,type(kwargs))#身高,国籍,出生地,学历
prinfInfo("张三",25,"男",身高=1.80,国籍="中国",出生地="江苏",学历="硕士")"""
姓名:张三,年龄:25,性别:男
{'身高': 1.8, '国籍': '中国', '出生地': '江苏', '学历': '硕士'} <class 'dict'>
"""
参数解包
在”函数调用“时,*和**的作用是:”解包“。
- 符号 * 将传进来的字符串、元组、列表、集合转化为多个标准参数
- 符号 ** 将传进来的字典,转化为多个关键字参数
def prinfInfo(name,age,gender,*args):print(f"姓名:{name},年龄:{age},性别:{gender}")print("作品评分自高到低为:",args)rate = [8.5,8.3,9.0]
rate = (8.5,8.3,9.0)
rate = {8.5,8.3,9.0} #无序prinfInfo("张三",25,"男",*rate)"""
姓名:张三,年龄:25,性别:男
作品评分自高到低为: (8.5, 8.3, 9.0)
"""
参数传递顺序
函数调用时,参数传递的顺序:
(调用时) 实际参数:位置参数、关键字参数
(定义时) 匹配形式参数顺序:args、*args、**kwargs
def testArgs(a,b,c=10,d=20,*args,**kwargs):print(f"a={a},b={b},c={c},d={d},args={args},kwargs={kwargs}")testArgs(1,2,3,c=4,5,6,7,x=100,y=200) #SyntaxError: positional argument follows keyword argument
#关键字参数之后不能再使用位置参数(只能使用关键字参数)def testArgs(*args,a,b,c=10,d=20,**kwargs):#可变参数在最前面时,匹配到关键字赋值的其他实际参数print(f"a={a},b={b},c={c},d={d},args={args},kwargs={kwargs}")testArgs(1,2,3,4,5,a=6,c=100,b=8,x=100,y=200)
"""
a=6,b=8,c=100,d=20,args=(1, 2, 3, 4, 5),kwargs={'x': 100, 'y': 200}
"""
命名关键字参数
*后面的参数,被称为“命名关键字参数”
def testStar(a,b,c,*,name,age):print(f"a={a},b={b},c={c},name={name},age={age}")testStar(1,2,3,name="张三",age=30) # *的作用,表示*后面的参数必须使用命名的方式来进行参数赋值
#name 和 age要使用命名的方式来赋值
"""
a=1,b=2,c=3,name=张三,age=30
"""
3. 返回值
返回值类型
函数可以返回全部数据类型,没有返回值时,默认返回为None
def test():pass# return "abc"# return 2.0# return True# return 200# return ["abc"]# return {"a":3}# return (3,5)# return {1,2,3}# return None #没有返回值时,默认返回为Noneres = test()
print(res,type(res))
返回多个值
返回多个值的函数,将需要返回的多个值,封装在列表、字典、元组容器中。
注意: set会改变数据的顺序
def divid(a,b):shang = a//byushu = a%breturn shang,yushures = divid(5,2)
print(f"商:{res[0]},余数:{res[1]}")
print(res,type(res))print(divid(5,2),type(divid(5,2)))
sh,yu = divid(5,2)
print(f"商:{sh},余数:{yu}")"""
商:2,余数:1
(2, 1) <class 'tuple'>
(2, 1) <class 'tuple'>
商:2,余数:1
"""
4. 局部变量和全局变量
局部变量
def test1():a = 100print("test1----修改前:",a,id(a))a = 300print("test1----修改后:",a,id(a))def test2():a = 100 #不同的函数可以定义相同名字的变量,彼此无关print("test2---------:", a, id(a))test1()
test2()
#print(a) #报错,局部变量只在函数内部有效"""
test1----修改前: 100 1190271473104
test1----修改后: 300 1190272768592
test2---------: 100 1190271473104
"""
注意:上面id打印的hash值每次运行都会不同,但是test1修改前和test2输出的a的id值是相同的
全局变量
全局变量:在文件内有效,能在多个函数中使用的变量。
a = 100 #定义全局变量def test1():print(a) #获取全局变量a,输出:100def test2():print(a) #输出:100test1()
test2()
print(a) #输出:100
在test1和test2的函数中,访问到的a都是100
全局变量和局部变量的作用域
全局变量和局部变量名字相同时,优先使用最近定义的变量。
有局部变量时,优先使用局部变量;没有局部变量时,看是否有全局变量。
a = 100
def test1():a = 300 #局部变量优先使用print("修改前,获取到局部的a:", a)a = 500 #修改局部变量的数值print("修改后,获取到局部的a:", a)def test2():#a = 1000print("test2获取到全局的a:",a) #没有局部变量,默认使用全局变量print("全局的a:",a)
test1()
test2()
print("test2执行后的全局的a:",a)"""
全局的a: 100
修改前,获取到局部的a: 300
修改后,获取到局部的a: 500
test2获取到全局的a: 100
test2执行后的全局的a: 100
"""
在函数中修改全局变量
在函数中修改全局变量前,需要在函数中声明变量为global被修改的全局变量,在其他函数中访问时数据也会跟着改变。
a = 100def test1():global a #在函数中声明全局变量的关键字:globala = 200print("test1.....",a)def test2():print("test2中的全局变量:",a)print("全局的:",a)
test1()
print("test1执行后全局的:",a)
test2()"""
全局的: 100
test1..... 200
test1执行后全局的: 200
test2中的全局变量: 200
"""
形式参数和局部变量
- 对于不可变参数,在函数内,每次都是让局部变量指向新的地址值所以a = 10,是局部变量a 指向了新数值的新地址,不影响外部的x。
- 对于可变参数,在函数内,是传递进来的(原有的)地址值上修改数据内容所以b.append(“bbb”),是修改了(和y相同的)地址空间的列表内容,所以外部参数内容会受影响。
def test(a,b):print(f"test函数中的变量值,初始,a={a},b={b}",id(b))a = 10b.append("bbb")print(f"test函数中的变量值,修改后,a={a},b={b}",id(y))x = 20
y = ["aaa"]
print(f"调用函数前,x={x},y={y}",id(y))
test(x,y)
print(f"调用函数后,x={x},y={y}",id(y))"""
调用函数前,x=20,y=['aaa'] 1937237600896
test函数中的变量值,初始,a=20,b=['aaa'] 1937237600896
test函数中的变量值,修改后,a=10,b=['aaa', 'bbb'] 1937237600896
调用函数后,x=20,y=['aaa', 'bbb'] 1937237600896
"""
5. 递归函数
1. 递归的概念
递归函数:
#递归函数:
#形式:自己调用自己的函数
"""
本质:循环通过循环运行相同的运算过程,每次改变输入参数获取返回值参与下一次循环[递]:递进、放入[归]:返回
"""
#打印从100到1的整数
for i in range(100,0,-1):print(i)def printNum(n):print(n) #执行的运算if n == 1: #最终结束条件return #返回的数值printNum(n-1) #printNum(99) #调用自身函数printNum(100)
递归的写法:
- 编写函数体(功能)
- 确定结束条件和返回值
- 调用函数自身,修改参数
2. 递归的运算过程
阶乘的概念:n! = n * (n-1)!
分析为函数表达式:
f(1) = 1 n <= 1
f(n) = f(n-1) * n n > 1
def fac(n):if n <= 1:return 1return fac(n-1) * n# 5*4*3*2*1
print(fac(5)) #120
使用递归,根据用户指定的项数,计算斐波那契数列对应位置的值。
斐波那契数列 (Fibonacci sequence)
0,1,1,2,3,5,8,13,21,34,55,89,144……
f(n) = n n<=1
f(n) = f(n-1) + f(n-2) n>1
def feb(n):if n == 0:return 0if n == 1:return 1return feb(n - 1) + feb(n - 2)
print(feb(9)) #34
更多推荐
Python学习9
发布评论