-
函数
-
什么是函数:函数就是一个个小小的‘加工厂’(Function),对将要到来的‘原料’(参数变量)进行一系列逻辑、数学运算以及其他的一些循环语句的操作。简单来说就是实现某中特殊作用和功能的载体。
-
为什么要用到函数:
-
-
-
许多相似的功能都能包装在一个函数之中,多次实现其作用,大大减少了代码的数量,并且提高了开发效率。
-
提高了程序的拓展性
-
-
-
如何去定义函数
-
def func(): # 其中函数名不得与关键字相同,而且函数名尽量做到见名知意 print('messi is the best football player') # 函数体代码,定义阶段不执行函数体代码 func() # 调用阶段 res = func() # 由于函数的优先级很高,所以在赋值阶段就直接强行打印了func() print(res) # 变量接收返回值时,打印的是None,说明func()并没有返回值
-
Attention!:调用阶段时,函数名(func)遇到括号就会执行函数体代码,并且其优先级最高,只有执行完函数后才能执行接下来的代码。
- 要解决调用函数没有返回值的问题,就必须用到return语句。
-
关键字return
-
分为以下几种情况
-
- 写return,返回的是None
-
def func(): l = ['messi','kobe','james'] while True: for i in l: if i == 'kobe': # 当i为kobe的时候 直接结束函数运行 # break return print('a6666666') # 这一行代码拥有都不会运行 print(i) res = func() # 强行打印 print(res) # 返回None
2. 写return,返回的是一个值(可以是任意的数据类型)
-
def func(): return 'messi' def func1(): return [10,24,23] def func2(): return {'name':'messi'} def func3(): return (10,) def func4(): return {10,24,23,44,56} def func5(): return True print(func(),func1(),func2(),func3(),func4(),func5())
3. 写return,返回多个值
-
def func1(): return 'messi','kobe','james' res = func1() print(res) # 将多个数据以元组的形式返回值 >>>('messi', 'kobe', 'james')
为什么会以元组的形式返回值:函数并不希望自己的数据被修改
4. 为了将数据返回成我们想要的数据类型,可以在return后面输入想要的数据类型格式
-
def func1(): return {'messi','kobe','james'} res = func1() print(res) # 将多个数据以集合的形式返回值 >>> {'james', 'messi', 'kobe'}
同理 如果是想要输出列表类型,就可以在字符串两边加上中括号的格式。
-
总结:(1)、并不是说只有在写了return的情况下,函数才拥有了返回值,而是不管在任何情况下函数都拥有返回值,只不过在没写return 的情况下,函数的返回值默认为None。
(2)、光写return的意义在于结束整个函数的运行,而不是返回值
-
参数
-
主体分为形参和实参,其中形参是函数在定义过程中,在括号中写的变量名,全称形式参数;而实参是函数在调用过程中,函数括号内的赋予变量名的值,全称实际参数。两者只在函数调用和定义过程中有着密不可分的练习,离开函数之后并无太大意义。简单来说调用函数就是利用实参来传给形参赋值执行函数体语句的过程。
-
格式:
-
函数的简易结构 def 函数名(形参1,形参2...): '''函数的注释 用来描述该函数的作用以及各个形参的类型''' 函数体代码1 函数体代码2 ... return 函数的返回值
-
def func(args): # 定义函数,命名形参 print(args) # 函数体语句 n = 0 for i in args: n += 1 return n print(func('messi')) # 给形参赋予实参的'messi'的值,执行函数体语句操作
-
其中形参又可以有很多形式的形参比如位置形参,默认形参,可变长形参等
-
位置形参
-
定义:在函数定义时,在括号中从左向右写的形参,并且在实参赋值时遵循着“先到先得”的原则,第一个实参就赋值于第一个位置形参,第二个实参就赋值于第二个位置形参。。。依次类推,并且赋值的实参个数必须与形参个数一致,否则会报错。
-
def func1(x,y): # 定义函数和形式参数的命名 if x > y: return x else: return y print(func1(10,20)) # 其中10为第一个参数所以其为x赋值,20为第二个实参则它为y赋值,从而输出为20
除了这种方法给位置参数赋值,还有一个方法给其赋值,那就是关键词传参,如下所示:
-
def func1(x,y,z): # 定义函数和形式参数的命名 if x > y and x > z: return x elif y > z: return y else: return z print(func1(10,80,z = 30)) # 关键字传参和位置传参一起用
print(func1(20,z = 90,x = 30)) # 其中第一个20传参给x,而后面30又传参给x,则报错不能对同一个参数传参两次
print(func1(20,z = 100 , y = 60)) # 关键字传参可以不按顺序,但一定不要对同一个形参赋两次值还有一个值得注意的是,位置参数必须放在关键词传参之前。
-
默认值参数
-
顾名思义,默认值参数的意思就是在函数定义过程中,形参已经被默认值给赋值了。因此在函数调用时,就不必为其赋值了,自然会调用默认值。如果调用参数时,不想使用默认值,只需要修改调用函数的实参来更换,实参取的什么,调用函数就传什么参数给形参。
-
def register(playername,age,gender='male'): # 形式参数必须排列在默认值参数之前 print(playername,age,gender) register('messi',31) register('kobe',43) register('james',32) register('lina',40,gender = 'female') # 如果函数调用的时候,实参与默认值参数不同,那么所传的参数就是实参所指定的值,不传默认值参数
还有一个要注意的点就是:函数形参中用到的值都是往定义阶段往上找就行了
-
可变长参数(*和**的使用)
- 一方面是因为传参是实参的参数个数不固定,超出了形参的参数个数范围,用来接收溢出的位置参数和关键字参数。
- 一方面是因为实参参数的格式会出现列表,字典,元组等数据类型,从而将他们用类型于for循环的方法一个个拆分。
-
*和**站在形参的角度来说,更像是将实参中冗余的数据做成一个大的容器类型的数据来赋值输出;站在实参的角度来说,更像是将赋值于形参的数据一个一个拆分成小的位置参数和关键字参数来调用。对于形参是揉和成团,而对于实参则是大卸八块。而且*是针对位置参数,**是针对关键字参数
-
站在形参上使用*
-
def func2(x,y,*z): # 形参来接收溢出的实参数据 print(x,y,z) func2('messi','agentina','barcelona','football','40') # 将从第三个参数之后的一起合在一起成为元组,赋值于形参
-
站在实参上使用*
-
def func2(x,y,z): print(x,y,z) func2(*['messi','agentina','barcelona']) # 将实参中的容器类型,按照类似for循环的方式拆分为可以赋值于形参的数据类型
-
站在形参上使用**
-
def func3(x,y,**z): # 将实参中溢出的关键字参数按照字典存放来进行赋值 return (x,y,z) res = func3(x = 'messi',y = 'agentina',z = 'barcelona',a = '40',b = 'football') print(res)
-
站在实参上使用**
-
def func3(x,y,z): print(x,y,z) res = {'x' : 'messi','y' : 'agentina','z' : 'barcelona'} func3(**res) # 将实参中的容器类型按照for循环的方式拆分成关键字参数传参