Python学习(10)--函数的调用和参数
1.函数存在的必要性
函数是一组具有特定功能的代码块,在程序中我们可能需要多次实现一个特定功能,这个时候,只需要实现这个具有特定功能的函数,而不需要多次重复的去编写这组代码块,即利用函数可以实现代码的重用.
当我们遇到一个比较大的问题的时候,可以将一个大的功能拆分成几个小的功能.这样做便于问题的简化,将复杂的难题分成几个模块函数去完成,大而化小.
在Python中有两种函数,一种是系统自带的函数,如raw_input(),print()等等,以及其他程序开发人员开发的第三方库,如TensorFlow,这些属于预定义函数.还有一种函数是系统不能提供给用户,需要用户自己定义并实现功能的函数,即自定义函数.
2.函数的定义和调用
如下图所示,定义了一个将两个数相加,并打印结果的函数:
在图中可以看到,def为定义一个函数的关键字,add为函数名,定义函数名需要注意的是,如果函数名由两个单词组成,第二个单词的首字母需要大写,如addNumbers.括号里是参数列表,这个函数是没有参数的,接着是一个冒号,最后是函数体,需要注意的是函数体中的语句前需要加一个Tab缩进符,以表示这个语句属于某个函数.如下代码定义了一个函数,并调用这个函数:
- def fun(S):
- print("you input:"+S)
- s=input("please input:")
- fun(s)
如上代码所示:定义了一个名为fun的函数,这个函数参数只有一个,代码fun(s)就是对这个函数的调用了,代码运行结果如下:
3.函数的实参和形参
- def fun(x,y):
- print('first input:'+x)
- print('second input:'+y)
- s1=input("first input:")
- s2=input("second input:")
- fun(s1, s2)
如上代码所示,fun(s1,s2)是为对函数fun(x,y)的调用,其中s1和s2就是实际参数,因为他们是函数运行过程中的用到的实际值,在调用的时候会执行,x=s1,y=s2这两个赋值语句,虽然在fun(x,y)函数运行过程中并不知道s2和s1的存在,但是x和y实际使用的值却是s1和s2的值,x和y只是形式参数,他们只是使用调用语句传过来的值,这一点可以通过打印内存地址来证明,代码如下:
- def fun(x,y):
- print('id(x):',id(x))
- print('id(y):',id(y))
- print('first input:'+x)
- print('second input:'+y)
- s1=input("first input:")
- s2=input("second input:")
- print('id(s1):',id(s1))
- print('id(s2):',id(s2))
- fun(s1, s2)
打印结果如下:
可以看到s1和x地址相同,s2和y地址相同,这说明s1和s2把值分别赋给x和y,大家需要注意的是在函数调用使用的参数是实参,在函数定义使用的参数是形参.
4.函数调用需要注意的事项
先看一个比较常用的函数调用代码:
- def machine(x,y):
- print('生成一个 ',x,'元',y+' 口味的冰激凌')
- machine(3, '草莓')
函数是一个"冰激凌生成器",参数有两个,一个是x,表示冰激凌的价格,另一个是y,表示冰激凌的口味,machine(3, '草莓')是一般情况下对函数的调用,代码结果如下:
再看一个函数调用的情况:
- def machine(x,y):
- print('生成一个 ',x,'元',y+' 口味的冰激凌')
- machine(3)
代码运行结果如下:
错误说明为,machine函数调用没有为参数y赋值,解决这种错误的方法有两种,一种是像之前那样函数调用时,添加一个实参,为形参y赋值,还有一种方法就是为形参y设置默认值,这个默认值,是当函数调用没有为形参赋值时,形参y可以使用这个默认值.如下代码:
- def machine(x,y='西瓜'):
- print('生成一个 ',x,'元',y+' 口味的冰激凌')
- machine(3)
- machine(3.'草莓')
代码运行结果如下:
第一次调用函数machine(x,y)时,并没有为y提供实参,这时y使用的是默认值,即y='西瓜',第二次调用函数machine(x,y)时,为y提供了实参,这个时候会实参会覆盖掉形参的默认值,即y='草莓'.
再看如下代码:
- def machine(x=3,y='西瓜'):
- print('生成一个 ',x,'元',y+' 口味的冰激凌')
- machine("草莓")
- machine(y="草莓")
如上代码所示,函数machine参数x和y都有默认值,函数调用machine('草莓'),在函数调用者眼中,'草莓'应该是第二个参数y的实参,但是python编译器却不这么解析,python会认为'草莓'这个实参是第一个形参x的实参,那么怎样才能让python认为'草莓'这个实参属于y呢,这需要程序调用者指定形参,例如machine(y='草莓'),语句y='草莓',就是指定实参'草莓'属于形参y.
代码运行结果如下:
这里我们需要注意的是,当在调用函数的时候,如果没有在调用的时候为实参指定形参,参数的赋值会依次从左至右为形参赋值,这里比如machine('草莓'),在没有为'草莓'指定形参的情况下,python解析到的是'草莓'为第一个形参x的实参.
在看一组代码,如下:
- def machine(x=3,y):
- print('生成一个 ',x,'元',y+' 口味的冰激凌')
- machine(y='草莓')
代码运行结果如下:
代码如下:
- def machine(x=3,y):
- print('生成一个 ',x,'元',y+' 口味的冰激凌')
- machine(x=3,y='草莓')
代码运行结果如下:
如下代码:
- def machine(x=3,y):
- print('生成一个 ',x,'元',y+' 口味的冰激凌')
- machine(3,'草莓')
代码运行结果如下:
从以上代码运行结果来看,无论如何调用函数,都相同的报了non-default argument follows default argument这个错误,其实这与函数的调用无关,是函数的定义出了问题,这里大家需要注意的是,如果一个参数具有默认实参,即形参在函数调用前有一个默认值 ,那么它后面所有的形参都应该是具有默认实参,比如machine(x=3,y),第一个形参x有默认实参,那么形参x后的所有形参都应改具有默认实参,即y也应该具有默认实参,否则程序调用就会出现问题,另外,调用函数时实参的顺序颠倒依然可以正确的给对应的形参赋值,但必须清楚的指明形参.如下:
- def machine(x=3,y='西瓜'):
- print('生成一个 ',x,'元',y+' 口味的冰激凌')
- machine(y='草莓',x=3)
代码运行结果如下:
如上所示,函数调用的时候并没有按照形参的顺序,但是为每个实参都指定了形参,这样python在解析时就会清楚的了解到,每个实参对应的形参,例如machine(y='草莓',x=3),将3和'草莓'分别指定形参为x和y,虽然与函数machine(x,y)的形参顺序不同,但是python解析时不会出错.
今天看了下博客,好久没有更了,这学期的课比较多,下学期时间可能会富余些,可以好好写博客了.