6.1函数的定义和调用
6.1.1定义函数
格式:
def 函数名 ([参数列表]):
["""文档字符串"""]
函数体
[return 语句]
6.1.2函数调用
格式:
函数名([参数列表])
python中函数可以嵌套定义
例如:
def add_modify(a,b):
result=a+b
print(result)
def test():
print("我是内层函数")
add_modify(6,6)
定义在函数内部的函数只能在函数内部调用
def add_modify(a,b):
result=a+b
print(result)
def test():
print("我是内层函数")
test()
add_modify(6,6)
6.2函数参数的传递
6.2.1 位置参数的传递
def get_max(a,b):
if a>b:
print(a,"是较大的值")
else:
print(b,"是较大的值")
get_max(6,5)
6.2.2关键字参数传递
形参=实参
def connect(ip,port):
print(f"设备{ip}:{port} 连接!")
connect(port=666,ip=999)
注意:如果定义函数的时候参数中有“/”
那么“/”前边的只能用位置参数传递,“/”后边的位置和关键字都可以。
6.2.3默认参数的传递
在定义时可以给参数传一个值,例如:
def connect(port,ip=666):
print(f"设备{ip}:{port} 连接!")
connect(port=999)
connect(ip=6,port=999)
需要注意的是,没有设定默认参数的形参定义时必须在前边
6.2.4参数的打包与解包
函数支持将实参以打包和解包的形式传递给形参。
- 打包:
如果函数在定义时不确定要传递几个值,那么可以在定义函数的时候为形参添加“*”或者“**”
"*"可以将接收的数据,以元组的形式打包成多个值,“**"可以将接收数据,椅子以·字典的形式打包成多个值。(突然发现python函数可以重复定义)
def test(*args):
print(args)
test(1,2,3,4,5,6,7,8,9,10)
def test(**args):
print(args)
test(a=1,b=2,c=3,d=4,e=5)
又试了下好像不是方法的重载
def test(*args):
print(args)
test(1,2,3,4,5,6,7,8,9,10)
def test(**args):
print(args)
test(a=1,b=2,c=3,d=4,e=5)
test(1,2,3,4,5,6,7,8,9,10)
书上说:*/**后的命名可以用任意的符合规范名字,但是建议用*args和**kwargs
如果函数没有接收到任何实参,那么,*args和**kwargs为空。
- 解包
如果调用函数时给的实参是元组,或者字典那么可以在调用的时候在元组前加”*“或字典前加“**”
def test(a,b,c,d,e,f,g):
print(a,b,c,d,e,f,g)
nums=(11,22,33,44,55,66,77)
test(*nums)
不知道为什么字典的元素的键还得和形参一样,好像就是把形参当成键然后字典中的值给到形参。
def test(a,b,c):
print(a,b,c)
nums={"a":11,"b":22,"c":33}
test(**nums)
6.2.5混合传递
混合传递就是说前边介绍的几种方式可以混合使用,但是前提是要有顺序。
比如:
位置、关键字、默认参数、打包
例如:
def test(a,b,c=33, *args,**kwargs):
print(a,b,c,args,kwargs)
test(1,2)
test(1,2,3)
test(1,2,3,4)
test(1,2,3, 4, e=5)
6.3函数的返回值
return返回。
过滤敏感词:
def filter_sensitive_words(words):
if "山寨" in words:
new_words=words.replace("山寨","**")
return new_words
result=filter_sensitive_words("这个手机是山寨版的吧!!!")
print(result)
还可以返回多个值。
def move(x,y,stpe):
nx=x+stpe
ny=y+stpe
return nx,ny
result=move(100,100,60)
print(result)
6.4变量作用域
6.4.1局部变量和全局变量
- 局部变量
局部变量指的是在函数内部定义的变量,他只能在函数内部被使用。函数调用完后,就没有了。
- 全局变量
在整个程序中都有作用。
在函数内部只能访问全局变量,不能修改全局变量。
number=10
def test_one(number):
number=number
print(number)
number+=1
print(number)
test_one(number)
print(number)
number=10
def test_one():
print(number)
number+=1
test_one()
print(number)
LEGB原则:
L(Local):局部作用域
E(Enclosing):嵌套作用域,嵌套定义的函数中外层函数声明的变量生效的区域。
G(Global):全局作用域
B(Built-in):内置作用域
6.4.2 global和nonlocal关键字
- global关键字
局部变量声明为全局变量,这样就可以在函数内部修改全局变量了。
格式:global 变量
number=10
def test_one():
global number
number+=1
print(number)
test_one()
print(number)
- nonlocal关键字
可以在局部作用域中修改嵌套作用域中声明的变量。
格式: nonlocal 变量
def test():
number=10
def test_in():
nonlocal number
number=20
test_in()
print(number)
test()
6.5特殊形式的函数
6.5.1递归函数
调用自身的函数。
两个条件:一个是递归公式、一个是边界条件
递归函数执行可以分为两个阶段:
(1)递推:递归本次的执行都基于上一次的运算结果。
(2)回溯:遇到终止条件时,则沿着递推往回一级一级返回来。
格式:
def 函数名([参数列表]):
if 边界条件:
return 结果
else:
return 递归公式
递归求阶乘:
(1)n=1时,所得结果=1
(2) n>1时,结果是:n*(n-1)!
n=1是边界条件
n*(n-1)!是递归公式
def func(num):
if num==1:
return 1
else:
return num*func(num-1)
num =int(input("请输入一个整数:"))
result=func(num)
print(f"{num}!=%d"%result)
6.5.2匿名函数
匿名函数是无需定义标识符的函数:
使用lambda定义
格式:
lambda <形参> :<表达式>
匿名函数和普通函数的区别:
1.匿名函数没有名字
2.匿名函数的函数体只能是一个表达式
3.匿名函数实现的功能比较简单
4.匿名函数不能被其他程序使用
定义好的匿名函数不能直接使用,最好用一个变量保存他,以便后期使用可以随时使用这个函数。
#定义匿名函数,并将它的函数对象赋值给变量temp
temp=lambda x : pow(x,2)
#此时变量temp可以作为匿名函数的临时名称来调用函数。
print(temp(10))