Day03-python基础函数
一 数学定义的函数与python中的函数
初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数。自变量x的取值范围叫做这个函数的定义域
例如y=2*x
python中函数定义:函数是逻辑结构化和过程化的一种编程方法。
python中函数定义方法: def test(x): "The function definitions" x+=1 return x def:定义函数的关键字 test:函数名 ():内可定义形参 "":文档描述(非必要,但是强烈建议为你的函数添加描述信息) x+=1:泛指代码块或程序处理逻辑 return:定义返回值 调用运行:可以带参数也可以不带 函数名()
补充:
1.编程语言中的函数与数学意义的函数是截然不同的俩个概念,编程语言中的函数是通过一个函数名封装好一串用来完成某一特定功能的逻辑,数学定义的函数就是一个等式,等式在传入因变量值x不同会得到一个结果y,这一点与编程语言中类似(也是传入一个参数,得到一个返回值),不同的是数学意义的函数,传入值相同,得到的结果必然相同且没有任何变量的修改(不修改状态),而编程语言中的函数传入的参数相同返回值可不一定相同且可以修改其他的全局变量值(因为一个函数a的执行可能依赖于另外一个函数b的结果,b可能得到不同结果,那即便是你给a传入相同的参数,那么a得到的结果也肯定不同)
2.函数式编程就是:先定义一个数学函数(数学建模),然后按照这个数学模型用编程语言去实现它。至于具体如何实现和这么做的好处,且看后续的函数式编程。
二.代码不适用函数会有什么问题:
1.无组织无结构
2.可读性差
3.无法实现统一管理,且维护成本
三.为什么要定义函数
总结使用函数的好处:
1.代码重用
2.保持一致性,易维护
3.可扩展性
函数要先定义后使用,如果没有定义而直接使用,就相当于引用了不存在的变量名
四.函数的介绍
1.在python中函数分为两类:内置函数和自定义函数
内置函数:求和:sum() 求最大值: max() 求幂: min() 计算长度:len()
示例:
a = len ([1,2,3,4]) print(a) b = max([1,2,6,4]) print(b)
自定义函数:(def 为自定义函数的关键字)
def foo(): # foo为函数名 print('*'*6) foo() # 调用函数 #输出:****** def a(): print('hello word') a() # 输出:hello word
2.函数的使用包括两个阶段:定义函数阶段和使用阶段
3.函数的语法:
def 函数名(参数1,参数2,......): # 可以定义多个参数
、、、文档注释、、、
函数体(代码)
return值(返回值)
4.定义函数的三种形式
4.1无参函数:如果函数的功能,仅仅只是执行一些操作而已,就定义为无参函数,无参函数通常都没有返回值
def foo(): # 定义函数阶段 print('*'*6) # 定义函数阶段 foo() # 使用函数阶段
4.2定义有参函数:函数的功能的执行,依赖于外部传入的参数,有参函数通常都有返回值
补充的知识点(三元表达式)
x = 10 y = 2 if x > y : print(x) else: print(y) #上面的代码等同于下面的三元表达式 res = x if x > y else y #(成立的条件放左边,不成立的放右边) print(res)
有参函数示例:
def my_max(x,y): res = x if x > y else y return res print(my_max(10,2))
4.3空函数
def auth(): '''认证功能''' pass auth()
5.调用函数
def foo(): print('from foo',) def bar(name): print('bar====>',name)
5.1按照有参和无参可以将函数调用分两种: 1.foo() # 调用无参函数(定义时无参) 2.bar('jim')#调用有参函数(定义时有参)
5.2按照函数的调用形式和出现位置分三种
1.foo()# 调用函数的语句的形式
def my_max(x,y): res = x if x > y else y return res
2.res = my_max(1,2)*1000 # 调用函数的表达式形式
3.res =my_max (my_max(10,20),30) # 把函数调用当中另外一个函数的参数
6. 函数的返回值
def foo(): print('from foo') res = foo() print(res) # 返回值None
以下三种情况返回值都是None
1.没有return
2.return 后面什么都不写
3.return None
当return一个值,函数调用赶回的结果就是这个值
def foo(): print('from foo') x = 1 return x res = foo() print(res)# 返回值 1
当return多个值时,返回值为元组的形式里面包括多个返回值
def foo(): print('from foo') return 1,2,3,4 res = foo() print(res) # 返回值 (1, 2, 3, 4)
补充的内容:序列的解压和return结合使用
# 序列的解压 t = (1,2,3) a,b,c = t print(a) print(b) print(c) # 序列的解压和return结合 def foo(): print('from foo') return 1,[2,3],(4,5),{} a,b,c,d = foo() print(d) # return里面有几个值就需要几个值接收
t = (1,2,3,4,5,6,7,8)
a,*_,c = t
print(a)
print(c)# 支取开头和结尾的值
7.函数的参数
7.1.从大的角度来看函数可以分为两类:形参,实参
定义阶段
def foo(x,y): # x y 为形参 定义阶段 print(x) print(y) foo(1,2) # 1 2 为实参 调用阶段
补充注意的内容:
函数定义阶段到底做了什么事情:
定义阶段只检测函数语法并不会执行,调用阶段找里面的代码,如果找不到提示找不到这个名字,
定义阶段只是定义x y之类的函数名,没有语法错误,只是个标识符,不占用内存空间,只有在调用阶段,才有传值得过程。
7.2详细的区分,函数的参数分为五种:位置参数、关键字参数、默认参数、可变长参数(*安然公司,**kwargs)命名关键字参数
7.2.1位置参数
def foo(x,y,z): # 位置参数:必须被传值的参数 print(x,y,z) foo(1,2,3) # 不会报错,位置是参数与形参一一对应 foo(1,2) # 会报错,因为定义了三个参数,只赋值了两个,所以会报错
7.2.2关键字参数 (key=value,唯一对应)
def foo(x,y,z): print(x,y,z) foo(z=3,x=1,y=2) # 关键字参数需要注意的问题:1.关键字实参必须在位置实参后面 foo(1,y=2,z=3)# 没有报错 foo(x=1,2,z=3)# 报错 # 2.不能重复对一个形参传值 foo(1,x=1,y=2,z=3) # 报错重复传值
7.2.3默认参数
def register (name,age,gender='man'): # 形参指定默认参数 print(name,age,gender) register('jim',20)# 指定完默认参数之后,不用赋值,默认打印gender指定的值 register('tom',18,gender='female') # 指定了默认参数也可以再赋值
默认参数需要注意的问题:
1.默认参数必须跟在非默认参数后(在定义阶段就会报错)
2.默认参数在定义阶段就赋值了,而且是在定义阶段赋值一次
a = 1000 def foo(x,y=a): print(x,y) a = 1 foo(1)
3.默认参数的值通常定义成不可变的类型
7.2.4可变长参数
# 1.
def foo(x,y,*args): # 把溢出的按位置定义的实参都接受,以元组形式赋值的形式赋值给args print(x,y) print(args) foo(1,2,3,4,5,6)
示例:
def foo(*args): res = 0 for i in args: res += i return res print(foo(1,2,3,4))
# 2. def foo(x,y,**kwargs): # 把溢出的按关键字定义的实参都接受,以字典形式赋值的形式赋值给kwargs print(x,y) print(kwargs) foo(1,2,a=3,b=4)
7.2.5命名关键字参数
def foo(name,age,*,sex,height):# *后面的定义发的参数为命名关键字参数,这类参数,必须被传值,而且必须以关键字实参的形式去传值 print(name,age) print(sex) print(height) foo ('jim',18,sex='man',height=180)
命名关键字参数:默认参数可以写在位置参数前面
def foo(name,age,*,sex=‘man’,height):
8.*args和**kwargs的其他用法:
def foo(*args): print(args) foo(1,2,3,4) # (1,2,3,4) 等同于 foo(*(1,2,3,4)) foo(*['a','b','c','d']) # 等同于 foo('a','b','c','d')
def foo(**kwargs): print(kwargs) # x=1,y=2 # 等同于 **{'y':2,'x':1} foo(x=1,y=2) # 等同于 foo(**{'y':2,'x':1}) foo(**{'y':2,'x':1}) # 等同于 foo(x=1,y=2)
def foo(x,y,z): print(x,y,z) foo(**{'y':2,'x':1,'z':3}) # 等同于 foo(x=1,y=2,z=3) foo(**{'y':2,'x':1}) # 等同于 foo(x=1,y=2) ,少了一个参数所以报错
def foo(x,y,z): print('from foo',x,y,z) def wrapper(*args,**kwargs): print(args) print(kwargs) foo(*args,**kwargs) wrapper(1,z=3,y=2) # 输出结果 from foo 1 2 3