python函数入门
1.初始函数
什么是函数?
函数,可以当做一大堆功能代码的集合
定义
def 函数名():
...
函数名()
例如:
def info():
print('1')
print('2')
info()
什么时候用函数?
- 有重复代码,用函数增强代码的复用性
- 代码太长,用函数增强代码的可读性
注意:以前写代码按照逻辑从上到下逐步完成,称为【面向过程编程】
利用函数编程称为【函数式编程】
2.函数的参数
2.1参数
- 在定义函数时,在括号中添加的变量,成为形式参数
def func(a1,a2,a3):
print(a1+a2+a3)
func(1,2,3)
-
在执行(调用)函数传入的参数,称为实参(实际参数)
func(1,2,3)
传参方式
-
位置传参(按照位置传入参数)
def add(a1,a2): print(a1+a1) add(1,2)
-
关键字传参
def add(a1,a2): print(a1+a2) add(a1=1,a2=2)
2.2默认参数
默认参数不传值,值就是默认值,传值就是传入的值
#a3=100就是默认参数 def add(a1,a2,a3=100): print(a1+a2+a3) add(1,2)
注意:关键字传参(位置和关键字混合时,关键字传参要在后面)
def add(a1,a2,a3=100): print(a1+a2+a3) add(1,2) add(1,2,3) add(1,2,a3=3) add(1,a2=2,a3=3) add(a1=1,a2=2,a3=3)
2.4 动态参数
- “*”
#*args元组类型
def func(*args):
print(args)
func(11) (11,)
func(11,22)
func() #空元组
-== **==
#**kwargs字典类型类型
def func(**kwargs):
print(kwargs)
func(a1='wxy') {"a1":'wxy'}
func() {}
-
*, **
def func(*args,**kwargs): print(args) (11,22,) print(kwargs) {'a1':'wxy'} func(11,22,a1='wxy')
注意事项
-
** 必须放在 *的后面
def func(*args,**kwargs):
-
参数和动态参数混合时,动态参数只能放在最后
def func(a1,a2,*args,**kwargs):
-
默认值参数和动态参数同时存在(参数,默认参数,,*args,**kwargs)
def func(a1,a2,a3=3,*args,**kwargs):
3.函数返回值
函数实现某功能后,返回结果给我们
def add(a1,a2):
return a1+a2
result=add(1,2)
print(result) 3
-
返回值可以是任意类型,如果没有写return,默认返回None
-
函数中 未写返回值 或 只写 return 或写 return None,返回结果都为None
-
return后面的值如果有逗号,默认会将返回值转换成元组再返回
def func(): return 1,2,3 value=func() (1,2,3)
-
函数中遇到return立即退出函数,终止所有代码,不管有多少层
4.参数的默认值
def func(a1,a2=10):
print(a1,a2)
面试中经常出现
原理:python再创建函数(未执行)时,发现函数的参数中有默认值,会在函数内部创建一块区域并维护这个默认值
- 执行函数未传值时,则让a2指向函数维护的默认值地址
- 执行函数传值时,则让a2指向新传入的值的地址
在特定情况下【默认参数的值是可变类型】&【函数内部修改这个值】,参数默认值有坑
- 坑
def func(a1,a2=[1,2]):
a2.append(666)
print(a1,a2)
#未传入默认值,a2指向默认内存地址【值为[1,2]】,在函数内部修改值,地址不变,值变化-》[1,2,666]
func(100)
#100,[1,2,666]
#未传入默认值,a2指向默认内存地址【值为[1,2,666]】,在函数内部修改值,地址不变,值变化->[1,2,666,666]
func(200)
#200,[1,2,666,666]
- 大坑
def func(a1,a2=[1,2]):
a2.append(a1)
return a2
#未传入默认值,a2指向默认内存地址【值为[1,2]】,在函数内部修改值,地址不变,值变化-》[1,2,10]
v1=func(10)
print(v1)
#[1,2,10]
#未传入默认值,a2指向默认内存地址【值为[1,2,10]】,在函数内部修改值,地址不变,值变化->[1,2,10,100]
v2=func(100)
print(v2)
#[1,2,10,100]
#传入默认值,a2指向传入默认值内存地址【值为[11,22]】,在函数内部修改值,地址不变,值变化->[11,22,200]
v3=func(200,[11,22])
print(v3)
#[11,22,200]
#未传入默认值,a2指向默认内存地址【值为[1,2,10,100]】,在函数内部修改值,地址不变,值变化->[1,2,10,100,1000]
v4=func(1000)
print(v4)
#[1,2,10,100,1000]
-
深坑
def func(a1,a2=[1,2]): a2.append(a1) return a2 #未传入默认值,a2指向默认内存地址【值为[1,2]】,在函数内部修改值,地址不变,值变化-》[1,2,10] v1=func(10) #未传入默认值,a2指向默认内存地址【值为[1,2,10]】,在函数内部修改值,地址不变,值变化->[1,2,10,100] v2=func(100) #传入默认值,a2指向传入默认值内存地址【值为[11,22]】,在函数内部修改值,地址不变,值变化->[11,22,200] v3=func(200,[11,22]) #未传入默认值,a2指向默认内存地址【值为[1,2,10,100]】,在函数内部修改值,地址不变,值变化->[1,2,10,100,1000] v4=func(1000) #v1,v2,v4指向的默认值内存地址,v3是传入的内存地址 print(v1) #[1,2,10,100,1000] print(v2) #[1,2,10,100,1000] print(v3) #[11,22,200] print(v4) #[1,2,10,100,1000]
5.动态参数
动态参数,定义函数是在形参位置用’或*'可以接任意个参数
在定义函数时,可以用’和*',在执行函数时,也可以用
-
形参固定,实参用*和**
def func(a1,a2): print(a1,a2) func(*[1,2]) func(**{'a1':1,'a2':2})
-
形参用"*和**",实参也用 “*和**”
def func(*args,**kargs): print(args,kargs) func([1,2,3],{'k1':1,'k2':2}) #整体为元组的一个元素 #([1, 2, 3], {'k1': 1, 'k2': 2}) {} func(*[1,2,3],**{'k1':1,'k2':2}) #(1, 2, 3) {'k1': 1, 'k2': 2}
https://www.luffycity.com/