什么是函数?它有什么作用?
函数是一个整体,你可以把你经常用的代码定义成一个函数,当你去调用这个函数的时候,就相当于用了整个函数里面的代码,里面的代码就是封装代码。注意,函数是一个整体,所以里面的变量是局部变量,在外面是用不了的,比如说我在函数里面设置a=5,在函数外面我们就用不了这个变量a
定义方法及调用方法如下:
1
2
3
|
def zhouyu(): #定义一个zhouyu的函数
print ( "i am zhouyu" ) #zhouyu函数内的封装代码
zhouyu() #调用zhouyu这个函数
|
执行结果
这个是没有参数的函数,一般情况下,函数里面可能有一些数是有变化的,这个数是就是参数,这个数可以由上面代码的结果,或者用户输入的值传到这个函数里面,代替这个参数让函数变得更可用。比如:
1
2
3
4
|
def sum_2_nums(a,b):
sum1 = a + b
print ( "%d + %d = %d" % (a,b,sum1))
sum_2_nums( 100 , 200 )
|
从上面的代码可以看出,我们定义了一个函数sum_2_nums,这个函数有两个参数,一个是a,一个是b,(注意:参数一般是写在函数的括号里面的)这两个参数就可以在封闭代码上应该了,如上面代码的第二行就可以知道a,b这两个参数被应用了,下面我们看第四行代码,可以看到这个函数被调用了,与之前调用的不同的是这个函数被调用的时候,还加上了两个数字,一个是100,一个是200,其实可以是这样的,我们调用这个函数的时候,代码就会去找有没有这个函数,如果有,就会执行这个函数,很显然,是有这个函数的,而且这个函数需要我们提供两个参数,一个为a,一个为b,那么我们在调用这个函数的时候,就得提供两个参数,如上代码,我们提供的参数就是100和200函数就会把a=100,b=200放入到这个函数代码中去执行,就会出现以下结果:
像上面的情况来说,a,b就是形参,而100,200就是实参,形参其实就是一个形象的参数,就是虚拟的,而实参就是实实在在的参数,比如100,200就是实际的参数。
如果你把上面代码的100,200换成别的,那a和b的值也会随着变化。
下面说return这个的作用
return就是把一个方法的执行结果返回出来,比如下面我们想获取sum1的结果,可以通过return获取
1
2
3
4
|
def sum_function(a,b):
sum1 = a + b
return sum1
print (sum_function( 100 , 200 ))
|
如果你没有加入return sum1的话,你去执行这个代码,sum_function(100,200)这个方法的结果是空的,也就是None,就什么都没有打印出来,因为这个函数没有返回任何数据。当然,也有另外一种方法,就是把这个sum1定义成一个全局变量,可以通过以下代码:
1
2
3
4
5
|
def new_sum(number):
global sum2
sum2 = number + 3
new_sum( 50 )
print (sum2)
|
执行结果是
global其实就是声明一个全局变量,这样我们就可以在外面应这个变量啦
有同学可能会说,那我要它的返回值干嘛,请看下面,如果new_sum想要拿到上一个方法的结果来当成我这个方法的变量,怎么办,因为函数里面的变量是局部变量,在外面是获取不到的,所以我们通过返回值来获取我们想要的东西:
1
2
3
4
5
6
7
8
|
def sum_function(a,b):
sum1 = a + b
return sum1
def new_sum(number):
sum2 = number + 3
print (sum2)
a = sum_function( 100 , 200 )
new_sum(a) |
当上面的代码执行到第7行代码的时候,就会去调用sum_function这个函数,并传入了两个数值,100和200.这时候就会去执行sum_function这个函数,因为这个函数里面有return,所以就会去return出来的值赋给了a,这样a就有值了,然后再把a的值赋给了new_sum这个函数
注意返回值可以多个,但是return只能有一个,因为方法在执行的时候,看到return它就不执行下面的代码,直接退出方法啦,那如果我们想返回多个值怎么办呢,返回值可以为任何类型,比如元组,字典,列表。这样的话,我们就可以把多个值放在字典或者元组或者列表里面
代码如下:
1
2
3
4
5
6
7
|
def sum_function(a,b):
sum1 = a + b
d = {a,b,sum1}
return d
a = sum_function( 100 , 200 )
print (a)
print ( type (a))
|
这样我们返回的就是一个set的数据类型
如果你想返回一个列表,可以用以下方法代码如下:
1
2
3
4
5
6
|
def sum_function(a,b):
sum1 = a + b
return {a,b,sum1}
a = sum_function( 100 , 200 )
print (a)
print ( type (a))
|
字典也是同理
如果你默认返回多个值的话,方法会把它封装成一个元组如下代码:
1
2
3
4
|
def sum_function(a,b):
sum1 = a + b
return a,b,sum1
print (sum_function( 100 , 200 ))
|
下面说一下函数的嵌套
下面代码是把把print_line函数嵌套在print_5_line函数上
1
2
3
4
5
6
7
8
|
def print_line():
print ( "-" * 50 )
def print_5_line():
i = 1
while i < = 5 :
print_line()
i = i + 1
print_5_line() |
上面的执行结果就可以说明函数是可以嵌套的。
下面说一下缺省参数,缺省参数就是参数有默认的值,如果你没有给这个参数值,这个参数就用它默认的值。如下代码中,zhouyu函数有两个形参a和b,也就是说我们去调用它的时候要传入两个参数,那为什么代码去调用zhouyu的时候只传入一个参数却没有报错呢,因为b=12是缺省参数,也就是说,如果只传入一个参数,那么b就会使用默认值也就是12,所以执行结果是sum = 13。
1
2
3
4
|
def zhouyu(a,b = 12 ):
sum1 = a + b
print ( "sum = %d" % sum1)
zhouyu( 1 )
|
如果你调用zhouyu的时候传入两个参数,那b=12就不生效啦,如下:
1
2
3
4
|
def zhouyu(a,b = 12 ):
sum1 = a + b
print ( "sum = %d" % sum1)
zhouyu( 1 , 22 )
|
执行结果是sum = 23
这里要注意一下,缺省参数只能放在最后,不能放在中间或者前面,如下面代码,一定会报错的:
1
2
3
4
|
def zhouyu(a = 12 ,b):
sum1 = a + b
print ( "sum = %d" % sum1)
zhouyu( 1 , 22 )
|
如果你有三个参数呢最后两个是缺省参数,然后你只想让第三个参数不要用默认值,用你传入的值,怎么办呢,可以看看下面代码:
1
2
3
4
|
def zhouyu(a,b = 12 ,c = 22 ):
sum1 = a + b + c
print ( "sum = %d" % sum1)
zhouyu( 1 ,c = 33 )
|
从上面代码可以看出b的默认值是12,c的默认值是22,那如果你想改变c的值而不改变b的值的话,你可以在传入参数的时候写上c=33,这样c就不会应用默认值22,而用33,像这种我们就称c=33是命名参数
这里我们是明确知道我们想要传入几个参数,那么,如果我们不知道自己想传入几个参数怎么办呢
1
2
3
4
5
|
def long_argue(a,b, * argue):
print (a)
print (b)
print (argue)
long_argue( 1 , 2 , 3 , 4 )
|
上面代码中,*argue是用来接收多余的参数的,我们可以看看执行结果
上面的代码中,把多余的3,4传入到argue这个参数里面,变成了一个元组,那么它有什么用呢,比如说,我们想让很多个值相加,可是不知道大概有多少个值,就可以通过这个来实现。如下代码:
1
2
3
4
5
|
def long_argue(a,b, * argue):
for i in argue:
sum1 = sum1 + i
sum1 = sum1 + a + b
long_argue( 1 , 2 , 3 , 4 )
|
由上面的代码就可以知道,把多余的3,4传入给了argue,这样argue就是一个元组啦,如果要让他们想加的话,就得把元组里面的值一个一个的取出来,并让它们相加,然后再让结果去加上a,b这样就可以实现多个值相加啦。
下面还有一种,就是在*argue后面加上**kwargue这个参数,那么它又是什么意思呢,可以看看下面代码的解释:
1
2
3
4
5
6
|
def long_argue(a,b, * argue, * * kwargue):
print (a)
print (b)
print (argue)
print (kwargue)
long_argue( 1 , 2 , 3 , 4 )
|
执行结果如下:
上面可以知道,其实我们的*argue是用来接收一些数值或字符串的,并把这些数据变成元组,而**argue是用来接收命名参数(什么是命名参数可以看看上面红色字体部分,有相关的解释),并把这些命名参数变成字典。
如果我们有一个元组和一个字典,现在想把元组和字典都传递到函数中,应该怎么做呢,可以看看以下代码:
1
2
3
4
5
6
7
8
|
def long_argue(a,b, * argue, * * kwargue):
print (a)
print (b)
print (argue)
print (kwargue)
A = ( 44 , 55 , 66 )
B = { 'name' : 'zhouyu' , 'age' : 22 }
long_argue( 11 , 22 , * A, * * B)
|
如果你不在第8行代码中,A和B前面加上*号的话,传入参数的时候就会默认把A和B看成一个整体,也就是字符串,然后把这两个字符串都传入到*argue这个参数里面去,就变成了元组的值。而上面代码就是把*A拆成一个个数字,也就是44,55,66的数值,然后传递给*argue,把B拆成"name"="zhouyu","age"=22,然后传入了B,像这种过程,我们称这为拆包