:函数是一种工具可以重复调用,防止代码的冗余,解决代码可读性差的问题。
定义函数:函数必须先定义后调用
def——定义函数的关键字
函数名:命名规范和变量是一样,要有意义,反应功能
函数分为:
有参函数——需要外部传来的参数
空函数——pass提前占位,先建立好程序构架,从而提高开发效率
调用函数:
函数的使用分为调用阶段和定义阶段,定义阶段只检测语法,不执行代码,函数名加括号既可以进行调用
调用函数分为三种方式
1.foo()直接家函数,或者 f= foo f()同样可以调用
2.表达式形式: n =foo(1,2) m = 10*foo(1,2) 返回值直接进行运算
3.foo(1,foo(2,3))作为参数的形式
函数的返回值:
1.不写return,或者return 后无值,再或者写return None ,返回值默认None
2,return返回一个值,可以将返回的值当变量使用
3,return返回多个值,可以将多个值存入元组,可用*打散。可以指定返回值数据类型
return是一个函数结束的标志,函数体代码只要遇到了return就停止函数
函数的参数
函数先定义后调用,不执行任何代码
形参:函数在定义阶段,在定义是的变量名,接受外部传来的值
实参:调用函数阶段,括号内传入的变量值,可以是变量,常量,表达式三者组合
形参实参的具体使用:
位置参数:
定义阶段:位置及顺序,从左到右,按这种定义的形参必须被传值
调用阶段:从左到右一一对应形参
关键字参数:
可以用key = value形式,调用阶段可以不按顺序传入,但必须在位置参数后边,并且不能对一个姓参重复赋值
默认参数:
在定义参数时就已经为参数赋值,默认参数必须在位置参数之后,默认参数的值仅在函数定义阶段赋值一次——在定义阶段已经确定,后续无法改变,默认参数通常设为不可变类型
疑惑点
def foo (n,arg = []): #这里边传的列表id都为一个列表,每一次添加都会加到列表后边 print(id(arg)) arg.append(n) return argprint(foo(1))print(foo(2,))print(foo(23))
def fo(n,arg =None): if arg is None: ###is 是判断id是否相等 arg = [] arg.append(n) return argprint(fo(1))print(fo(2))print(fo(3))还有一种在解决办法: def foo (n,arg = []): print(id(arg)) arg.append(n) return arg print(foo(1,[])) print(foo(2,[])) print(foo(23,[])) 直接传入新的列表可变长度参数
参数长度可变主要是为了防止调用函数时候实参个数不确定
*args 接受溢出位置参数,放形参
接收后以元组的形式保存下来赋值给该形参
def foo (x,y ,args): print(x) print(y) print(args)l = [1, 2, 3]print(foo(1,2,l)) *l可以打散传入的容器类型
**kwargs 接收所有溢出的关键字参数,以字典的形式保存下来
def foo (x, **kwargs): print(x) print(kwargs)print(foo(y = 1,x = 2,z = 3))
如果事先生成了字典,任然可以传给**kwargs
def foo(x,y,kwargs): print(x) print(y) print(kwargs)dic = {'a ':1,'b':2}print(foo(1,2,dic))
def foo(x,y,kwargs): print(x) print(y) print(kwargs)dic = {'a ':1,'b':2}print(foo(1,2,dic))###如果没有*就变成了普通的位置参数,如果一个就会打散字典(key),定义函数时候没有*arg的话也会溢出