函数:
函数是组织好的,可重复使用的,实现单一功能的代码段
函数有输入(参数)和输出(返回值)
Python中,函数是一等对象(first class)
一.函数的定义与调用:
- 基本语法
def fn():
pass
- 带函数的参数:
def add(x, y):
return x + y
- 有赋值就创建新的变量:
x = 1
y = 2
def swap(x, y):
x, y = y, x
swap(x, y)
x
>1
y
>2
- 通过list修改变量[因为并没有修改变量,所以将会返回append追加的内容]:
lst = [1, 2, 3]
def append(item):
lst.append(item)
append(4)
lst
[1, 2, 3, 4]
二.位置参数和关键字参数:
通过位置传递参数的叫位置参数
- 位置参数和关键字参数:
def add(x, y):
print()
add(1, 2) 位置参数
add(x=1, y=2) 关键字参数
- 位置参数和关键字参数可以混合使用,但是关键字参数要在位置参数后面.否则会报错SyntaxError
add(1,y=2)
三.可变参数:
非默认非可变参数, 可变位置参数,可变关键字参数
默认参数不要和可变参数放到一起
def print_info(x, y, *args, **kwargs): //自动组装成一个字典
print(x)
print(y)
for x in args:
print(x)
for k, v in kwargs.items():
print('{0} {1}'.format(k, v))
print_info(1, 2, 3, 4, 5, 6, name='roach',age=16)
x => 1
y => 2
可变参数为(3, 4, 5, 6)
可变关键字参数为:
name roach
age 16
1/可变位置参数:
def sum(lst):
ret = 0
for x in lst:
ret += x
return ret
sum([1, 2, 3, 4, 5]) //这里需要传入一个list
# 变成 可变参数
def sum(*args): //自动组装成一个元组
ret = 0
for x in args:
ret += x
return ret
sum(1, 2, 3, 4, 5)
2/可变关键字参数:
def print_info(**kwargs): //自动组装成一个字典
for k, v in kwargs.items():
print('{0} {1}'.format(k, v))
print_info(name='roach',age=16)
> name roach
> age 16
3/可变位置参数和可变关键字参数混合:
- 可变参数函数在定义的时候,就决定了参数是位置参数还是关键字参数
def print_info(*args, **kwargs): //自动组装成一个字典
for x in args:
print(x)
for k, v in kwargs.items():
print('{0} {1}'.format(k, v))
print_info(name='roach',age=16)
> name roach
> age 16
四.参数解包 [重要] :
a = [1, 2, 3]
b = {'a':1, 'b':2, 'c':3}
def fn(a, b, c):
pass
fn(*a)(1)
fn(**b)(1)
fn(*[1, 2], **{'c':3})(3)
1.可以用 * 解包列表或者元组作为位置参数
2.可以用**解包字典为关键字参数
3.也可以混合使用,思考:fn([1, 2],*{'c':3, 'a':4})会怎么样?
例子1 - 列表[参数解包]:
lst = [1, 2]
def add(x, y):
print(x)
print(y)
add(*lst) //参数解包
例子2 - 字典[参数解包]:
d = {'x':1, 'y':2}
def add(x=1, y=3): //key 要和非可变形参一一对应
print(x)
print(y)
add(**d)
五.默认参数:
默认参数的坑: 列表
当形参是可变类型的时候就会发生这种情况:
def fn(lst = []):
lst.append(1)
print(list)
解决办法:
def fn(lst = None):
if lst is None:
lst = []
lst.append(1)
print(list)
六.函数返回值:
可以通过type来查看函数的返回值;
函数默认return None;
def add():
pass
type(add())
七.递归函数:
函数体内条用自身的函数
递归函数需要有合适的退出条件
迭代都可以转换成递归
递归不一定可以转化为迭代
python递归最大深度为1000,且不支持尾递归优化
python中应尽量避免使用递归
八.作用域与全局变量:
作用域: 变量生效的范围
局部变量:在函数体内定义的变量, 局部变量作用域为函数体
输出当前的全局变量和局部变量:
print(globals())
print(locals())
九.函数的调用过程:
def add(x, y):
def inc(x):
def main():
x = 1
y = 2
ret = add(x, y)
ret =inc(ret)
print(ret)
十.生成器:
def iterator(x):
i = 0
while i < 5:
yield i
i += 1
def main():
for i in iterator(5):
print(i)
main()
1.先执行main函数.
2.执行到iterator 将main函数压栈;执行iterator函数.
3.执行到yield,将 i = 0 放入main的命令空间,同时把iterator压栈,暂停,调出main函数;
4.然后就重复1-3步骤,直到while条件不满足,逐步退出函数;
def iterator():
lst = [1, 2, 3, 4, 5]
yield from lst
for x in iterator():
print(x)
- 通过生成器求积数:
def fn(x):
ret = 1
for i in range(1, x +1):
ret *=i
yield ret
for x in fn(5):
print(x)
1
2
6
24
120
it = fn(5)
it.next() //生成器可以生成可迭代对象;
//遍历到最后一个完后会返回,StopIteration;
浙公网安备 33010602011771号