一 函数的定义与调用
现在需要一个程序来实现len()的功能。
计算字符串 s 长度
s='好好学习' #函数的定义
def my_len(): i = 0 for k in s: i +=1 print(i) #函数的调用 length = my_len() print(length)
上面就是咱们写了一个函数,并且成功的调用了它。
定义: def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。 def 是固定的,不能变,他就是定义函数的关键字。 空格 为了将def关键字和函数名分开,必须空,当然你可以空2格、3格或者你想空多少都行,但正常人还是空1格。 函数名:函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并能表达函数功能 括号:是必须加的! 注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。 调用:
就是 函数名() 要记得加上括号。
上面的程序虽然实现了功能但是还不够完美:
## 没有返回长度,只是单纯的打印
## 不能变,只能计算s字符串的长度,换一字符串就得修改一下函数
为了解决以上问题引入了返回值和参数的概念
二 函数的返回值
如何让自定义的函数和len函数一样,有返回值呢?那就是在函数的最后加上一个return,return 后面写你需要的返回值就可以了。
def my_len(): #自定义函数
i = 0 for k in s: i +=1 return i #返回值 length = my_len() print(length)
return的主要作用就是返回值和结束整个函数。返回值有几种情况:没有返回值、返回一个值、返回多个值。
#返回值的三种情况: # 没有返回值 #不写return --- 默认返回None #只写return ---- 结束一个函数 # return None ---- 不常用 # 返回一个值 #可以返回任何数据类型 #只要返回了就可以接收到 #如果在一个程序中有多个return,只执行第一个return # 返回多个值 #返回多个值用多个变量接受:有多少个返回值就用多少变量接收 #用一个变量接收所有返回值:得到的是个元祖
返回多个值实例
#多个变量多个返回值 def func1(): return 1,2 r1,r2=func1() print(r1,r2) #一个变量接收所有返回值 def func1(): return 1,2 r=func1() print(r) #返回一个元祖(1,2)
补充知识:
#列表、元祖、字典都是可以解包的
a,b,c=[1,2,3] print(a,b,c) d,e,f=(4,5,6) print(d,e,f) g,h,i={'k1':'v1','k2':'v2','k3':'v3'} print(g,h,i)
执行结果
1 2 3
4 5 6
k1 k2 k3
三 函数的参数
现在,我们已经把函数返回值相关的事情研究清楚了,我们自己已经完成了一个可以返回字符串长度的函数。但是现在函数只能计算s字符串的长度,换一字符串就不行了,下面就来看一下函数的参数。
def my_len(s): #自定义函数---接收参数、形式参数,简称形参 i = 0 for k in s: i +=1 return i #返回值 s = '好好学习' ret = my_len(s) #传递参数--传参,实际参数,简称 实参 print(ret) print(my_len('天天向上'))
我们告诉mylen函数要计算的字符串是谁,这个过程就叫做 传递参数,简称传参,我们调用函数时传递的这个“天天向上”和定义函数时的s就是参数。
形参和实参
参数还有分别:
我们调用函数时传递的这个“天天向上”被称为实际参数,因为这个是实际的要交给函数的内容,简称实参。
定义函数时的s,只是一个变量的名字,被称为形式参数,因为在定义函数的时候它只是一个形式,表示这里有一个参数,简称形参。
参数的四种情况
#参数 #没有参数 #定义函数和调用函数时括号里都不写内容(就是我们最原始的my_len()) #有一个参数 #传什么参数就是什么(上面的my_len()函数)
#有多个参数
#位置参数
#关键字参数
实参总结:
#站在实参的角度上: #按照位置传参 #按照关键字传参 #混着用传参:但是 必须先按照位置传参,再按照关键字传参 #不能给同一个变量传多个值
1. 位置参数
def my_sum(a,b): res = a+b return res print(my_sum(1,2))
2. 关键字参数
def my_sum(a,b): res = a+b return res print(my_sum(a=2,b=1))
3. 位置、关键字形式混着用
def my_sum(a,b): res = a+b return res print(my_sum(2,b=1))
实参总结
站在形参的角度上: #位置参数:必须传,且有几个参数就传几个值 #默认参数:可以不传,如果不传就用默认的参数,如果传了就用传的
4. 默认参数
默认参数实例
def classmate(name,sex='男'): print('{} : {}'.format(name,sex)) classmate('小明') classmate('小花') classmate('小红','女')
参数总结:
#定义函数的时候: #位置参数:直接定义参数 #默认参数:关键字参数:参数名 = ‘默认值’ #动态参数:可以接收所有的参数 #定义方式 # 参数名前加* #参数名习惯用args #参数名前加**,习惯参数名kwargs #顺序:必须先定义位置参数,*args,后定义默认参数
5. 动态参数
动态参数有两种:可以接受任意个参数
#*args: 接收的是按照位置传参的值,组织成一个元祖
#**kwargs: 接收的是按照关键字传参的值,组织成一个字典。
# *args
def sum(*args): n = 0 for i in args: n +=i return n print(sum(1,2)) print(sum(1,2,3)) print(sum(1,2,3,4)) def func(*args): print(args) func(1,2,'str',['list',1]) def func(*args,l=[]): print(args,l) func(1,2,'str',['list',1],l=[1,2,3,4])
# **kwargs def func2(**kwargs): print(kwargs) func2(a=1,b=2,c=3) func2(a=1,b=2) func2(a=1)
动态参数的另一种传参方式
1)传列表
def func(*args): #站在实参的角度上,给一个序列加上*,就是将这个序列按照顺序打散。 print(args) func(1,2,3,4,5) l=[1,2,3,4,5] func(*l) #站在实参的角度上,给一个序列加上*,就是将这个序列按照顺序打散 执行结果: (1, 2, 3, 4, 5) (1, 2, 3, 4, 5)
2)传字典
def func(**kwargs): print(kwargs) func(a=1,b=2) d = {'a':1,'b':2} func(**d) #站在实参的角度上,给一个字典加上*,就是将这个字典按照顺序打散 执行结果 {'a': 1, 'b': 2} {'a': 1, 'b': 2}
四 函数的注释
def func(): ''' 说明这个函数实现了什么功能 参数说明 :return: 返回值的类型 '''